iphone - minimumzoomscale - uiview developer




UIScrollViewがサブビューをタッチする (3)

誰かがnoobを並べ替えるのを手伝ってもらえますか? 私はこの問題をさまざまなフォーラムに投稿して答えを得ていませんでしたが、他の回答の検索が多かったのでstackOverflowが登場しました。

私は、Stone.h(UIImageViewのサブクラス、石のランダムPNG、タッチを受け入れるためのuserInteractionEnabled = YES)の乱数で覆われたBeachView.h(UIScrollViewのサブクラス、砂浜の写真)を持っています。

ユーザーがビーチに触れて移動すると、スクロールする必要があります。 ユーザーが石をタップすると、メソッド "touchedStone"を呼び出す必要があります。 ユーザーが石がないところのビーチをタップすると、メソッド "touchedBeach"を呼び出す必要があります。

さて、私はこれが死んで単純に聞こえると思います。 UIScrollViewにコントロールを渡す必要があることを受け入れる何かがあれば、みんなとすべてが私に語ります。 だから私が触れてドラッグすると、それはスクロールする必要があります。 しかし、私がタップし、それが石の上にある場合、それはビーチのタップを無視し、石のタップを受け入れるべきですか?

しかし、両方のビューがタップを受け入れ、touchedStoneとtouchedBeachの両方を呼び出すようです。 さらに、ビーチタップが最初に発生するので、「touchedStoneを入れてからtouchedBeachを実行しない」タイプのフラグを入れることさえできません。

ここにいくつかのコードがあります。 On BeachView.m


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     if (self.decelerating) { didScroll = YES; }
        else { didScroll = NO; }

     UITouch *touch = [[event allTouches] anyObject];
     CGPoint touchLocation = [touch locationInView:touch.view];
     NSLog(@"touched beach = %@", [touch view]);
     lastTouch = touchLocation;
     [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
     didScroll = YES;
     [super touchesMoved:touches withEvent:event];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
     if (didScroll == NO && isPaused == NO) { 
          [self touchedBeach:YES location:lastTouch];
     }
     [super touchesEnded:touches withEvent:event];
}

Stone.mについて


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     [parent stoneWasTouched]; // parent = ivar pointing from stone to beachview
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch *touch = [[event allTouches] anyObject];
     CGPoint touchLocation = [touch locationInView:touch.view];
     NSLog(@"touched stone = %@", [touch view]);
     [parent touchedStone:YES location:touchLocation];
}

石のタップの後、My NSLogは次のようになります:


Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched Stone = <Stone: 0x1480c0>
ran touchedStone

それで、実際には両方を実行しています。 touchesBeganとtouchesEndedをStone.mから取って、userInteractionEnabled = YESのままにしておくと、beachViewの両方のレジスタに自身が触れられますが、タッチしたビュー(2回目)としてStoneを返します。


Touched beach = <BeachView: 0x1276a0>
ran touchedBeach
Touched beach = <Stone: 0x1480c0>
ran touchedBeach

ですから、私はこれを数日間並べ替えようとしています。 どのように私はそれを作るようにタップ石はtouchedストーンだけ呼び出すとタップビーチは触れただけで呼びますか? どこが間違っていますか?


iPhone OS 3.0より前のバージョンでは、UIScrollViewのhitTest:withEvent:メソッドは常にselfを返し、UIEventを直接受け取ってスクロールまたはズームに関連しないと判断した場合にのみ適切なサブビューに転送します。

私は本当にNDAの下にあるので、iPhone OS 3.0についてコメントできませんでしたが、iPhone OS 3.0ベータ5のiPhone SDKリリースノートを確認してください:)

3.0より前をターゲットにする必要がある場合は、BeachViewでhitTest:withEvent:をオーバーライドし、CGPointが実際に石に入っている場合に次のビーチタッチを無視するフラグを設定できます。

しかし、オーバーライドされたメソッドの終わりから最初に[super touches *:withEvent:]への呼び出しを単純に移動しようとしましたか? これは石タップが最初に発生する可能性があります。



私はsimpleViewと同様の問題があったし、それはscrollViewに追加され、私がsimpleViewに触れるたびに、touchを取得するために使用されるscrollViewとsimpleViewの代わりに、 scrollView移動しました。 これを避けるために、ユーザーがsimpleView触れたときにscrollViewのsrcollingを無効にしました。そうしないと、スクロールが有効になりました。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    UIView *result = [super hitTest:point withEvent:event] ;
    if (result == simpleView)
    {
        scrollView.scrollEnabled = NO ;
    }
    else
    {
        scrollView.scrollEnabled = YES ;
    }

    return result ;

}