PanGesture 和 Tap Gesture 之间的冲突
Posted
技术标签:
【中文标题】PanGesture 和 Tap Gesture 之间的冲突【英文标题】:Conflict btwn PanGesture and TapGesture 【发布时间】:2016-08-08 17:21:36 【问题描述】:我的应用由一副纸牌组成。卡片组中的大多数卡片都是在 draggableView 中制作的。我正在努力做到这一点,以便在屏幕上双击将使我在卡上的按钮消失/重新出现。阅读此post 后,我尝试尝试一下。我将 UITapGesture 放入了我的 draggableView 类的 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 识别器之间存在错误。我该如何解决?
编辑:仍未解决,但如果我将 tapGesture 添加到可拖动视图(因此,self)而不是 _backgroundScrollView,我会收到此错误:
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类型,然后继续, How to compare the types of gestures on ios?的可能重复 我尝试了该线程中提供的解决方案,但仍然得到相同的 sig abrt 错误:/ 【参考方案1】: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;
【讨论】:
我实现了gestureRecognizer:(将UILongPressGestureRecognizer更改为UIPanGestureRecognizer)和gestureRecognizerShouldBegin,但仍然得到同样的错误:/ 你是否按照我的回答更改了gestureRecognizerShouldBegin? 是的,我把它改成了你上面给出的——仍然是同样的错误 好的,请用您刚才的尝试更新您的问题,我们会看看有什么问题。 我更新了gestureRecognizerShouldBegin 方法。请尝试一下。 @MaddieElizabeth【参考方案2】:我的错误: 在我的 h 文件中,我需要使用 draggableView 作为 tapGesture 的委托,然后将 gestureRecognizer 插入 UIGestureRecognizerDelegate 协议,如下所示:
@protocol UIGestureRecognizerDelegate <NSObject>
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
@end
【讨论】:
以上是关于PanGesture 和 Tap Gesture 之间的冲突的主要内容,如果未能解决你的问题,请参考以下文章
当 UITextField 位于 UIScrollView 内时,使用 Tap Gesture 关闭键盘的问题。
Swift 3 - 带有 Tap Gesture 的图像视图
IB Tap Gesture Recognizer 总是从 Outlet Collection 返回第一个视图