100

次のようなビュー階層があります。

UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel

UIView (B) にジェスチャ認識機能を追加しました。私が直面している問題は、UIView (B) 内にある Rounded Rect Button のアクションが得られないことです。singleTap ジェスチャ レコグナイザは、ボタンの Touch Up Inside イベントをキャプチャ/オーバーライドします。

どうすればそれを機能させることができますか? レスポンダー チェーン階層により、ボタン タッチ イベントが確実に優先され、トリガーされると思いました! 私は何が欠けていますか?

関連するコードを次に示します。

#pragma mark -
#pragma mark View lifecycle (Gesture recognizer setup)

- (void)viewDidLoad {
    [super viewDidLoad];

    // double tap gesture recognizer
    UITapGestureRecognizer *dtapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGestureRecognizer:)];
    dtapGestureRecognize.delegate = self;
    dtapGestureRecognize.numberOfTapsRequired = 2;
    [self.viewB addGestureRecognizer:dtapGestureRecognize];

    // single tap gesture recognizer
    UITapGestureRecognizer *tapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureRecognizer:)];
    tapGestureRecognize.delegate = self;
    tapGestureRecognize.numberOfTapsRequired = 1;
    [tapGestureRecognize requireGestureRecognizerToFail:dtapGestureRecognize];
    [self.viewB addGestureRecognizer:tapGestureRecognize];

    // add gesture recodgnizer to the grid view to start the edit mode
    UILongPressGestureRecognizer *pahGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognizerStateChanged:)];
    pahGestureRecognizer.delegate = self;
    pahGestureRecognizer.minimumPressDuration = 0.5;
    [self.viewB addGestureRecognizer:pahGestureRecognizer];

    [dtapGestureRecognize release];
    [tapGestureRecognize release];
    [pahGestureRecognizer release];
}

#pragma mark -
#pragma mark Button actions

- (IBAction)buttonTouchUpInside:(id)sender {
    NSLog(@"%s, %@", __FUNCTION__, sender);
}

#pragma mark -
#pragma mark Gesture recognizer actions


- (void)singleTapGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
    NSLog(@"%s", __FUNCTION__);
}

- (void)doubleTapGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
    NSLog(@"%s", __FUNCTION__);
}

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

    switch (gestureRecognizer.state) {

        case UIGestureRecognizerStateEnded: {
            NSLog(@"%s", __FUNCTION__);

            break;
        }
        default:
            break;
    }
}
4

9 に答える 9

179

「shouldReceiveTouch」メソッドでは、タッチがボタンにある場合に NO を返す条件を追加する必要があります。

これは、Apple SimpleGestureRecognizersの例からのものです。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    // Disallow recognition of tap gestures in the segmented control.
    if ((touch.view == yourButton)) {//change it to your condition
        return NO;
    }
    return YES;
}

それが役立つことを願っています

編集

ダニエルが指摘したように、それが機能するには準拠する必要がありますUIGestureRecognizerDelegate

シャニ

于 2011-01-28T05:49:34.240 に答える
51

私も同じ問題を抱えていたので、試してみました

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{

    if ([touch.view isKindOfClass:[UIButton class]]) {      //change it to your condition
        return NO;
    }
    return YES;
}

現在は完全に機能しています........

于 2011-07-26T05:53:06.810 に答える
20

一般的に言えば、以下のデリゲート メソッドを使用して、あらゆる種類の UIControl でのタッチを回避します。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (([touch.view isKindOfClass:[UIControl class]])) {
         return NO;
    }
    return YES;
}

注: このチェックを行わないでください (recognizer.view クラス タイプをチェックしてください)、gestureRecognizerShouldBegin は機能しません。

于 2012-09-04T07:53:08.853 に答える
11

Swift 3.0バージョンは次のとおりです。

extension UIViewController: UIGestureRecognizerDelegate {

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if touch.view is UIButton {
        return false
    }
    return true
}

次のことを忘れないでください。

Make your tapper object delegate to self (e.g: tapper.delegate = self)

于 2016-12-07T16:12:37.357 に答える
6

これがSwiftバージョンです:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if (touch.view!.isKindOfClass(UIButton)) {
        return false
    }
    return true
}

次のことを忘れないでください。

  1. クラスに準拠させるUIGestureRecognizerDelegate
  2. タッパー オブジェクトを自分自身に委任します (例: tapper.delegate = self)
于 2015-12-28T19:28:14.863 に答える