手势识别器和按钮动作

Mus*_*afa 96 iphone conflict uibutton ibaction uigesturerecognizer

我有一个看起来像这样的视图层次结构:

UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel
Run Code Online (Sandbox Code Playgroud)

我已将手势识别器附加到我的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

sha*_*oga 173

在"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;
}
Run Code Online (Sandbox Code Playgroud)

希望它会有所帮助

编辑

正如丹尼尔所说,你必须遵守UIGestureRecognizerDelegate它才能发挥作用.

SHANI

  • 请记住遵守UIGestureRecognizerDelegate协议并将UIGestureRecognizer的委托设置为该对象. (11认同)
  • UIGestureRecognizer行为被明确描述为与"正常"响应者链分开.这是Apple的设计决定. (2认同)
  • 为了更广泛的使用,请考虑Ramesh或flypig的测试条款的一些变体.在我的例子中,例如,我最终得到了一行:`if([touch.view isKindOfClass:[UIControl class]] || [[touch.view superview] isKindOfClass:[UITableViewCell class]]){`...请注意,tableview单元格在其contentView中被"触摸",这是私有类的成员,因此我们检查superview的类. (2认同)

Ram*_*n A 50

我也有同样的问题,然后我尝试了

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

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

它现在正常工作.........

  • 我只错过了'myGestureRecognizer.delegate = self;` (4认同)

fly*_*pig 20

一般来说,我们使用下面的委托方法来避免各种UIControls的触摸:

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

注意:请勿执行此检查(检查识别器.view类类型)gestureRecognizerShouldBegin,它将无法正常工作.


Mar*_*tti 10

这是一个Swift 3.0版本:

extension UIViewController: UIGestureRecognizerDelegate {

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

别忘了:

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


rsc*_*rsc 6

这是一个Swift版本:

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

别忘了:

  1. 让你的班级符合 UIGestureRecognizerDelegate
  2. 让你的攻丝机的对象授人以自我(如:tapper.delegate = self)


Lon*_*kly 5

我想到的最好的解决方案是使用下面的代码片段:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    CGPoint touchLocation = [touch locationInView:self.view];
    return !CGRectContainsPoint(self.menuButton.frame, touchLocation);
}
Run Code Online (Sandbox Code Playgroud)