2013-03-17 12 views
27

私はいくつかの 'サブビュー'を含むUIView( 'コンテナビュー')を持っています。私はUITapGestureRecognizerをコンテナビューに追加して、コンテナビュー内のリージョンをタッチしたときにアクティブになるようにしたいが、サブビューの外側に追加したい。現時点でUIGestureRecognizerからサブビューを除外する

、サブビューがジェスチャ認識を活性化させる内を含む、コンテナビュー内の任意の場所に触れます。コントローラでは :

実装は次のようになります

ContainerView *containerView = [[ContainerView alloc] initWithSubViews:array]; 
UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc] initWithTarget:self action:@selector(someSelector)]; 
[containerView addGestureRecognizer:tap]; 
[self.view addSubView:containerView]; 

ContainerView.m

-(id)initWithSubviews:(NSArray *)array { 
    for (subView *s in array) { 
     [self addSubView:s]; 
    } 
    return self; 
} 

で私はサブビューがされた後、ジェスチャ認識装置が追加されるため、問題が発生したと思います。それが本当であれば、ソリューションはinitWithSubViewsメソッドを2つの独立したメソッドに分割する必要があります。あなたがContainerViewためUITapGestureRecognizerを追加した場合、それはContainerView各地で応答しなければならない

はあなたに

答えて

9

のiOS 6は、まさにこの問題を解決素晴らしい新機能紹介 -​​ UIViewの(サブビュー)がに添付gestureRecognizerShouldBegin:(ジェスチャー認識からNOを返すことができますスーパービュー)。実際、それはいくつかのジェスチャ認識器(例えば、スーパービューに添付されたUITapGestureRecognizerに関するUIButton)に関するUIViewサブクラスのデフォルトです。

は、このトピックに関する私の本を参照してください:http://www.apeth.com/iOSBook/ch18.html#_gesture_recognizers

0

ありがとうございます。それはそのサブビューを気にしません。そのあなたのサブビューの位置に、ちょうどジェスチャー操作をスキップする場合

は、ジェスチャーの場所を確認してください。

- (void) tapGestureHandler:(UIGestureRecognizer *) gestureRecognizer { 


    CGPoint tapPoint = [gestureRecognizer locationInView:nil]; 

    //check your tapPoint contains ur subview frame, skip.else do ur actions 
} 
+0

多くのサブビューを確認する必要がある場合、これは高価で毛深いものです。 – CodaFi

+0

ええ。私は..私は他の良い解決策を見ていない..もしあなたが共有することを自由に感じる:) :) –

0

を追加しました:私はちょうどより良い何かを考え

。 gesture.viewがスーパーであれば、あなたのハンドラで

-(void)tapGestureHandler:(UITapGestureHandler)gesture 

チェック。 サブビューがタップされている場合、サブビューが返されます。

============================================== ======

私はスーパーの中に上書きを示唆しています。

​​

これはジェスチャーが

はそれがデフォルトでどのように動作するかを確認するには、この質問への回答を参照してくださいビュー内にあるかどうかを判断するために呼び出されます。

Event handling for iOS - how hitTest:withEvent: and pointInside:withEvent: are related?

ポイントは、そのサブビューのいずれかである場合は、確認することができます。はいの場合はnilを返し、そうでなければselfを返します。

サブビューのそれぞれにおける

OR

、何もしませんtapgesture認識を追加します。サブビューのジェスチャ認識プログラムは、デフォルトでスーパービューのジェスチャ認識プログラムをキャンセルします。私は多くのサブビューがある場合、私はメモリのフットプリントに目を維持するだろう。

+0

残念ながら私はこれが動作するとは思わない。ドキュメントによると、gesture.viewには「ジェスチャー認識機能が付いているビュー」が表示されます。サブビューではなく、コンテナビュー全体が表示されます。 2番目のオプションは有望に見えます。 –

+0

偉大な、私はヒットテスト:withEventメソッドを使用して作業している。以下の記事を参照してください。 –

11

私はそれは次のようにして作業を取得するために管理:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandler:)]; 

// ... 

-(void) tapGestureHandler:(UITapGestureRecognizer *)sender { 
    CGPoint point = [sender locationInView:sender.view]; 
    UIView *viewTouched = [sender.view hitTest:point withEvent:nil]; 
    if ([viewTouched isKindOfClass:[ThingIDontWantTouched class]]) { 
     // Do nothing; 
    } else { 
     // respond to touch action 
    } 
} 
37

私は、以下の簡単な方法を使用していました。 それはperpectly動作します!

は、サブビューにtouchsを受け入れない、スーパーにのみtouchs受け入れ、UIGestureRecognizerDelegate機能を実装します。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    if (touch.view != _mySuperView) { // accept only touchs on superview, not accept touchs on subviews 
     return NO; 
    } 

    return YES; 
} 
4

は、デリゲートメソッドに追加し、設定することを忘れないでください - あなたのUIViewControllerの.hファイルで

を含めますこのデリゲート

次にどこに作成しますかその後、タップ用デリゲートメソッドは、現在のタップに発火するデリゲートメソッドtap.delegate = self;を設定するために覚えて(例えば内のviewDidLoad)UR tapGestureオブジェクト、

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(actionMethodYouWantToHappenOnTap)]; 

    tap.delegate = self; //Remember to set delegate! Otherwise the delegate method won't get called. 

    [self.view addGestureRecognizer:tap]; 

。特定のサブビューが表示されていた場合は、タップジェスチャー認識を希望するときに扱うこのメソッド内で

を使用することが、私のコードで私は願っています

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ 

    if (!mySubview.hidden){ 
    return NO; //This fired if said subview was visible, though whatever the condition of where and when you want tap to work, can be handled within this delegate method. 
    } 

    return YES; 
} 

これは他の誰を助けタップを無視することを望んでいました同じ問題で私が見つけたデリゲートメソッドを設定することを忘れてしまったのは、簡単に見落とされるものでした。

乾杯

2

多くの回答があり、別の解決策が追加されています。サブビューのビュータグを初期化しますが、次の1とからタッチを受信して​​行うにはしたくない:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; 
    tap.delegate = self; 
    [self.view addGestureRecognizer:tap]; 
} 

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    if (touch.view.tag == 1) { 
     return NO; 
    } 
    return YES; 
} 

-(void)handleTap:(id)sender 
{ 
//Handle tap... 
} 

この方法では、タッチジェスチャーはあなたからそれを必要とするビューから受信されます。