你可以在 touchesBegan 之后强制取消触摸事件吗?

Posted

技术标签:

【中文标题】你可以在 touchesBegan 之后强制取消触摸事件吗?【英文标题】:Can you force a touch event to cancel after touchesBegan? 【发布时间】:2009-07-23 06:37:10 【问题描述】:

鉴于我的一个 UIViews 的某种状态,我希望它响应 touchesBegan,然后取消从该特定 touchesBegan 事件继续的任何进一步的 touchesMoved/Ended。

基本上我有一个 UIView 子类处于静止状态,如果它被触摸,我想将其他一些 UIView 移开......然后下次触摸它时,响应者链可以正常响应 touchesMoved/Ended......

是的,我可以在 touchesMoved/Ended 中检查此状态,但我想知道是否有办法在中间阶段破坏该触摸事件。

【问题讨论】:

【参考方案1】:
    let fakeTouch:Set<NSObject> = [UITouch()]
    let event     = UIEvent()

    self.touchesEnded(fakeTouch, withEvent: event)

【讨论】:

请为您的代码工作的原因添加一些解释,以便将来的用户可以轻松理解它。【参考方案2】:

删除视图层次结构的视图

这是一篇很老的帖子,没有令人信服的答案,所以我决定添加我的解决方法

使用 Xcode 9、Swift 4 和 ios 11,这些解决方案不会中断触摸

self.resignFirstResponder()
self.touchesEnded(touches, with: event)

我发现的解决方法如下:

let superview = self.superview
self.removeFromSuperview()
superview?.addSubview(self)

这在纯代码项目中很容易实现。我没有使用Storyboard 中的视图对其进行测试。

您需要确保管理视图层次结构,以防您可以在子视图堆栈中的同一点恢复视图。我将标签分配给视图以管理 superview.subviews 数组中的位置

【讨论】:

【参考方案3】:

我没有尝试过,但我有一个有根据的猜测。

第一响应者是触摸事件的当前接收者。因此,辞去第一响应者的职务应该会阻止更多的触摸事件进入。新的触地将设置一个新的第一响应者。

[self resignFirstResponder];

【讨论】:

有根据的猜测很好,OP 做测试工作没问题,不响应结果并删除或修复您的答案 -1【参考方案4】:

假设你有一个触摸,触摸对象总是相同的,这意味着你可以使用==进行比较

UITouch *anyTouch = [touches anyObject];
if (anyTouch != self.lastTouch)
     return;

因此,通过将最后一个 UITouch 存储在您的 UIView 子类中(在示例中,我使用了一个名为 lastTouch 的属性),您可以确定哪些触摸是您想要忽略的,哪些是您想要识别的移动并结束/取消。不优雅也不那么直接,但它可以让你得到你想要的。

当然,这可以扩展为多次触摸。

【讨论】:

【参考方案5】:

据我所知,UIScrollView 能够取消触摸。所以我想有一些方法可以做到这一点。抱歉,我无法提供更精确的解决方案。

【讨论】:

以上是关于你可以在 touchesBegan 之后强制取消触摸事件吗?的主要内容,如果未能解决你的问题,请参考以下文章

TVOS UIViewController 没有收到 touchesBegan 或 touchesMoved

Apple Watch 强制触控菜单

在 `touchesBegan:withEvent:` 之后禁用所有 UIPanGestureRecognizer

iOS 上 MonoTouch 中的多点触控

你如何知道在 touchesBegan 中被触摸的对象是啥?

iOS:检测触地、segue、触地