手势识别和按钮动作

手势识别和按钮动作

问题描述:

我有一个看起来是这样的视图层次:手势识别和按钮动作

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按钮的任何操作。 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; 
    } 
} 
+0

最简单的方法是设置cancelsTouchesInView =假 – 2017-06-02 10:10:12

在你要补充一点,将不返回触摸是否在按钮的条件了“shouldReceiveTouch”的方法。

这是来自苹果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为它工作。

SHANI

+1

啊!是的,我忘了这个-gestureRecognizer:shouldReceiveTouch:方法。感谢您指点我正确的方向。虽然这解决了我的问题,但我仍然不知道为什么响应者层次结构在这种情况下不起作用。它可能应该,但它不是由苹果公司处理。 – Mustafa 2011-01-28 07:29:25

+2

UIGestureRecognizer行为被清楚地描述为与“普通”响应者链分开。 这是由Apple设计决定的。 – 2011-02-17 12:48:15

我也有同样的问题,那我就用

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

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

它现在完美的工作.........

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

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

注意:不要做这种检查(C heck the recognitionizer.view类类型)gestureRecognizerShouldBegin,它不会工作。

最好的解决办法是在我的脑海使用下面的代码片段:

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

这里是一个斯威夫特版本:

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

不要忘记:

  1. 让你类符合UIGestureRecognizerDelegate
  2. 使您的tapper对象de legate to self(例如:tapper.delegate = self

这是斯威夫特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)