Pan 手势和 Tap 手势之间的冲突

Conflict btwn PanGesture and TapGesture

我的应用程序由一副纸牌组成。卡片组中的大多数卡片都是在 draggableView 中制作的。我正在努力做到双击屏幕将使我的按钮出现在卡片上 disappear/reappear。读完这个 post 后,我试着尝试一下。我将 UITapGesture 放入我的 draggableView class 的 initWithFrame 方法中,如下所示:

- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self) {
    [self addSubviewFromNib];
    [self setupView];
    panGestureRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(beingDragged:)];
    cardWidth = frame.size.width;
    cardHeight = frame.size.height;
    type = 0;
    panGestureRecognizer.delegate = self;
    panGestureRecognizer.cancelsTouchesInView = NO;
    _backgroundScrollView.panGestureRecognizer.cancelsTouchesInView = NO;
    //...more code above....
    _backgroundScrollView.userInteractionEnabled = YES;
    tapGestureRecognizer = [[UITapGestureRecognizer alloc]   initWithTarget:_backgroundScrollView action:@selector(doubleTap)];
    tapGestureRecognizer.delegate = _backgroundScrollView;
    tapGestureRecognizer.numberOfTapsRequired = 2;
[_backgroundScrollView addGestureRecognizer:tapGestureRecognizer];
[self addGestureRecognizer:panGestureRecognizer];

}

 - (void) doubleTap: (UITapGestureRecognizer *)tapGesturerecognizer{

    _mapButton.hidden = !_mapButton.hidden;
    _menuButton.hidden = !_menuButton.hidden;
    _phoneButton.hidden = !_phoneButton.hidden;
    reviewButton.hidden = !reviewButton.hidden;
    _shareButton.hidden = !_shareButton.hidden;

}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    // If the gesture recognizer is a UITapGestureRecongizer, but the other
    // gesture detected is a UIPanGestureRecognizer, require the
    // UITapGestureRecognizer to fail.
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
        [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    } else {
        return NO;
    }
}



- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        return YES;
    }
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gestureRecognizer;
        CGPoint velocity = [panGesture velocityInView:self];
        return fabs(velocity.y) <= fabs(velocity.x);
    }
    return YES;
}

但是,如果我双击,我会收到这个 sib abrt 错误:

 -[UITapGestureRecognizer velocityInView:]: unrecognized selector sent to instance 0x7f9f9a244230
 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITapGestureRecognizer velocityInView:]: unrecognized selector sent to instance 0x7f9f9a244230'

我假设这意味着 PanGestureRecognizer 和 TapGesture Recognizer 之间存在错误。我该如何解决?

编辑:仍未解决,但如果我更改要添加到可拖动视图(因此,自身)而不是 _backgroundScrollView 的 tapGesture,我会收到此错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DraggableView doubleTap]: unrecognized selector sent to instance 0x7fefdd9e4f70'

其他编辑:我将其改回 backgroundScrollView,现在我将其视为错误:

[UIScrollView doubleTap]: unrecognized selector sent to instance 0x7fe5130af000

gestureRecognizerShouldBegin 将被调用,每当手势识别器即将处理触摸时,它可能是点击手势,也可能是平移手势。您需要检查 gestureRecogniser 类型,然后再继续。

实现以下方法(取自here)以允许同时识别手势:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    // If the gesture recognizer is a UITapGestureRecongizer, but the other
    // gesture detected is a UIPanGestureRecognizer, require the
    // UIPanGestureRecognizer to fail.
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
        [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])  {
       return YES;
    } else {
       return NO;
    }
}

而在另一个委托方法中,崩溃原因告诉您:

-[UITapGestureRecognizer velocityInView:]: unrecognized selector sent to instance 0x7f9f9a2

velocityInView 被错误的手势类型调用,为避免此类错误,请按如下方式修改您的委托方法:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
{
  if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {     
       return YES;
  }
  if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { 
       UIPanGestureRecogniser *panGesture = (UIPanGestureRecongiser *)gestureRecogniser;    
       CGPoint velocity = [panGesture velocityInView:self];
       return fabs(velocity.y) <= fabs(velocity.x);
  }
   return YES;
}

我的错误: 在我的 h 文件中,我需要使用 draggableView 作为 tapGesture 的委托,然后将 gestureRecognizer 插入到 UIGestureRecognizerDelegate 协议中,如下所示:

@protocol UIGestureRecognizerDelegate <NSObject>
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
@end