如何告诉 UIGestureRecognizer 取消现有的触摸?

Posted

技术标签:

【中文标题】如何告诉 UIGestureRecognizer 取消现有的触摸?【英文标题】:How can I tell a UIGestureRecognizer to cancel an existing touch? 【发布时间】:2010-10-14 21:43:43 【问题描述】:

我有一个UIPanGestureRecognizer 用于跟踪用户手指下方的对象 (UIImageView)。我只关心 X 轴上的运动,如果触摸偏离 Y 轴上对象框架的上方或下方,我想结束触摸。

我已经获得了确定触摸是否在对象的 Y 范围内所需的一切,但我不知道如何取消触摸事件。翻转识别器的 cancelsTouchesInView 属性似乎并没有达到我想要的效果。

谢谢!

【问题讨论】:

【参考方案1】:

这个小技巧对我有用。

@implementation UIGestureRecognizer (Cancel)

- (void)cancel 
    self.enabled = NO;
    self.enabled = YES;


@end

来自UIGestureRecognizer @enabled 文档:

禁用手势识别器,使其 不接收触摸。默认 值为是。如果你改变这个 手势时属性为 NO 识别器当前正在识别一个 手势,手势识别器 转换到取消状态。

【讨论】:

OP 似乎在询问取消手势中的单个触摸,而不是完全取消手势。 不错的最小解决方案 WWDC 2014 Session 235: Advanced Scrollviews and Touch Handling Techniques 推荐使用此技术。 这将在 UIGestureRecognizerStateBegan 之后立即调用 UIGestureRecognizerStateCancelled 并终止该平移手势。【参考方案2】:

@matej 在 Swift 中的回答。

extension UIGestureRecognizer 
  func cancel() 
    isEnabled = false
    isEnabled = true
  

【讨论】:

【参考方案3】:

对象-C:

recognizer.enabled = NO;
recognizer.enabled = YES;

斯威夫特 3:

recognizer.isEnabled = false
recognizer.isEnabled = true

【讨论】:

【参考方案4】:

apple docs这个怎么样:

@property(nonatomic, getter=isEnabled) BOOL enabled

禁用手势识别器,使其不接收触摸。默认值为是。如果在手势识别器当前正在识别手势时将此属性更改为 NO,则手势识别器将转换为取消状态。

【讨论】:

【参考方案5】:

根据文档,您可以对手势识别器进行子类化:

在 YourPanGestureRecognizer.m 中:

#import "YourPanGestureRecognizer.h"

@implementation YourPanGestureRecognizer

- (void) cancelGesture 
    self.state=UIGestureRecognizerStateCancelled;


@end

在 YourPanGestureRecognizer.h 中:

#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>

@interface NPPanGestureRecognizer: UIPanGestureRecognizer

- (void) cancelGesture;

@end

现在你可以从任何地方拨打电话

YourPanGestureRecognizer *panRecognizer = [[YourPanGestureRecognizer alloc] initWithTarget:self action:@selector(panMoved:)];
[self.view addGestureRecognizer:panRecognizer];
[...]
-(void) panMoved:(YourPanGestureRecognizer*)sender 
    [sender cancelGesture]; // This will be called twice

参考:https://developer.apple.com/documentation/uikit/uigesturerecognizer?language=objc

【讨论】:

【参考方案6】:

只需在 handlePan(_ recognizer: UIPanGestureRecognizer) 方法中将 recognizer.state 设置为 .ended.cancelled

【讨论】:

【参考方案7】:

你有几种处理方法:

    如果您正在编写自定义平移手势识别器子类,您可以通过在识别器内部调用-ignoreTouch:withEvent: 来轻松完成此操作,当您发现它偏离您关心的区域时。

    由于您使用的是标准 Pan 识别器,并且触摸 开始 OK(所以您不想使用委托功能阻止它),您真的只能让当您收到识别器的目标操作时,您的区别。检查translationInView:locationInView:返回值的Y值,并适当钳制。

【讨论】:

问题是如何忽略识别器并在其操作中将触摸事件传递给其他人?

以上是关于如何告诉 UIGestureRecognizer 取消现有的触摸?的主要内容,如果未能解决你的问题,请参考以下文章

如何向 UIGestureRecognizer 添加 segue

UIGestureRecognizer 如何识别被点击的圆圈?

如何将 UIGestureRecognizer 限制为特定的 UIView?

如何从自定义 UIGestureRecognizer 触发 NavigationController 的 interactivePopGestureRecognizer

如何使用 UIGestureRecognizer 交换视图

如何在不阻止 textView 触摸的情况下向所有 UITextView 添加一个 UIGestureRecognizer