调用 touchescancelled 而不是 touchesended

Posted

技术标签:

【中文标题】调用 touchescancelled 而不是 touchesended【英文标题】:touchescancelled is called instead of touchesended 【发布时间】:2012-04-26 00:40:52 【问题描述】:

我试图在触摸时点亮一个视图,并在触摸结束时取消它。在执行此操作时,我注意到当我从视图中抬起手指时,不会调用 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 方法,而是在视图上调用 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 方法。这是正常的行为吗?我认为如果由于系统问题(如内存不足警告)而取消触摸,则会调用touchesCancelled。我通过使用 touchesCancelled 完成了我的工作,但我想知道为什么它不能正确调用 touchesEnded。是bug吗?

【问题讨论】:

这不是正常行为。我怀疑这是一个错误。答案完全取决于您的项目。没有看到代码的所有相关部分,任何人都无法开始推测。 您遗漏了太多信息,无法回答这个问题。重做或扔掉。与此同时,任何有此问题的人都应该查看他们提取接触点的视图。如果您的接触点数据来自,例如 [touches.anyObject locationInView:touches.anyObject.view],请尝试 [touches.anyObject locationInView:[actual reference to view]]。这将解决一大堆问题。 【参考方案1】:

这不是正常行为。抬起手指时,应该调用 touchesEnded。

当您的视图在触摸期间被移除或发生系统事件(例如,当您的手指触摸屏幕时锁定手机)时,应该调用 touchesCancelled

请参阅 touchesEnded 和 touchesCancelled 的文档。

没有您的代码,就不可能知道发生了什么。但是,即使您设法按应有的方式调用了 touchEnded,您似乎也希望对这两种情况都做出响应。迅速:

class MyView: UIView 
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        stopGlow()
    

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) 
        stopGlow()
    

    private func stopGlow() 
        //Your code here...
    

【讨论】:

【参考方案2】:

当您触摸该视图并抬起手指时,不应拖动手指。如果你这样做了,那么touchesCancelled: 方法将被调用。所以我认为你的观点太小而无法触及。如果是,则制作一个大视图并重试。然后它会为你工作。

将此视为comment..

【讨论】:

【参考方案3】:

我遇到过一种情况,使用自动 UIModalPresentationOverFullScreen 呈现文档窗口会导致窗口即使是模态窗口也可以上下移动一点。当我通过跟踪其父视图的触摸来移动子视图时,调用 touchesCancelled 就足够了。如果我抓住子视图的边缘并且手指移动得太快,显示的窗口会移动一点,它会取消触摸,这又称为 touchesCancelled。

【讨论】:

【参考方案4】:

您遗漏了太多信息,无法回答这个问题。重做或扔掉。与此同时,任何遇到此问题或其他与 touchesBegan/Moved/Ended/Cancelled 相关的意外行为的人都应该查看他们提取接触点的视图。如果您的接触点数据来自[touches.anyObject locationInView:touches.anyObject.view],请使用另一个对视图的引用,例如self.view 或类似的。这将解决一大堆问题。

【讨论】:

【参考方案5】:

如果触摸在开始后的第一秒左右没有移动足够远,看起来就像是调用了 touchesCancelled 而不是 touchesEnded。如果我做了一个小而快的动作,touchesCancelled 会触发,因为总动作不够大;如果我慢慢地做一个小动作,touchesCancelled 将在动作完成之前触发,因为 ios 放弃等待看我是否会进一步移动。显然,iOS 正在判断有多少移动是“重要的”,并将小移动视为取消触摸。

如果有帮助,您可以简单地从 touchesCancelled 调用 touchesEnded。但是在一个非常快速的移动的情况下,直到超时时间才会调用它,因此在移动实际结束和触发 touchesCancelled 的时间之间可能会有延迟。

顺便说一句,我还注意到,如果你做了一个小而快的动作,然后抬起手指,然后开始另一个动作,在触发 touchesCancelled 之前,这不被认为是一个新动作,并且 touchesBegan 不会触发。这使我的应用程序中的手写功能变得复杂,因为手写都是关于小而快的动作。

【讨论】:

以上是关于调用 touchescancelled 而不是 touchesended的主要内容,如果未能解决你的问题,请参考以下文章

UIControl 子类正在接收“touchesCancelled”而不是“touchesEnded”

touchesEnded 或 touchesCancelled 并不总是被调用

在 UIScrollView 中滚动而不触发 touchesCancelled

iOS:获取本机弹出窗口时未获取 touchesCancelled

什么是 touches cancelled 事件,它与 touches end 有什么不同

在滚动视图上拖动视图:已收到 touchesBegan,但没有 touchesEnded 或 touchesCancelled