UIGestureRecognizer 状态。为啥没有像“空闲”这样的状态?

Posted

技术标签:

【中文标题】UIGestureRecognizer 状态。为啥没有像“空闲”这样的状态?【英文标题】:UIGestureRecognizer states. Why there's no state like "idle"?UIGestureRecognizer 状态。为什么没有像“空闲”这样的状态? 【发布时间】:2012-03-03 16:17:40 【问题描述】:

有没有人知道为什么苹果设计UIGestureRecognizer 默认状态是“可能的”(手势识别器尚未识别它的手势,但可能正在评估触摸事件。这是默认状态。 ) 而不是像“空闲”这样的东西?

在我看来,“空闲”状态通过消除“但可能正在评估触摸事件”部分会更有意义和有意义。 “空闲” - 当 UIGestureRecognizer 没有收到任何触摸并且没有执行任何分析(触摸、计时器......)时。一旦它收到第一次触摸,它就会将其状态更改为“可能”,表明它执行某种分析(识别逻辑)。


*上下文: 我正在为另一个平台编写类似的架构。因此,这种状态将有助于将实际上正在做某事的手势识别器与那些没有收到任何触摸或只是忽略它们的手势识别器区分开来(用于实现 requireGestureRecognizerToFail 方法)。

【问题讨论】:

并非试图捍卫 Apple 的命名法,但它们在 离散手势 识别器和 连续手势 识别器之间确实存在差异。 Possible 实际上似乎比 idle 本身更适合空闲状态的名称。嗯,我有什么意义吗:) @rokjarc 我在这里看不到与离散和连续类型的联系。他们的“可能”可能意味着识别器内部发生了某些事情(例如,一些计时器正在运行或一些触摸被跟踪并计算偏移量)以及那里根本没有发生任何事情。当根本没有任何事情发生时,我认为“空闲”更有意义。我们在重置时进入的状态,直到第一次触摸到来。 【参考方案1】:

我们必须从finite state machines 的角度来思考。我的大学自动机文本:Automata and Computability Dexter Kozen。

手势识别器是一组状态,包括possible (P)、cancelled (C) 和ended (E)。 P 是开始状态,CE 是最终状态。在一端P 和另一端CE 之间,存在一系列状态,我们称它们为家庭S*。并且在所有各种状态之间存在由触摸事件和计时器事件触发的转换。 PS*CE 的特殊排列以及它们之间的转换,赋予了特定手势识别器功能。

例如,假设我们希望单点触控识别器在用户执行单点触控 (1td) 之后调用方法,然后在 0.5 秒内执行单点触控 (1tu)。否则我们希望它取消。所以我们得到以下机器:

(P,1td) -> S
(S,1tu) -> E
(S,.5s) -> C

拼写出来:

When in state `possible`, upon receipt of a single touch-down event, transition to state `S`.
When in state `S`, upon receipt of a single touch-up event, transition to state `ended`.

当我们到达状态ended 时,手势识别器会执行我们的回调。因此,仅这两个就可以了,除了有时间要求 - 用户必须在触摸后 0.5 秒内释放他的触摸,否则手势不是真正的单次触摸。所以我们有第三部作品:

When in state `S`, if a .5 second timer triggers (`.5s`), then enter state `cancelled`.

此外,我们可能还有很多其他可能发生的事情,例如“三个触地得分”(3td) 事件。所有这些其他事情都会立即使机器进入cancelled 状态。所以我们可能有(以及许多其他的)这个产品:

(P,3td) -> C

等等。

因此,我们可以将手势识别器可视化为一台大型机器,它将输入事件字母表中的“字母”作为输入,接受(结束)该字母表中的某些字符串集,并拒绝(取消)其他字符串。对于那些还不知道的人 - 这是正则表达式的理论基础。没错——手势识别器只是对触摸和计时事件字母表上的正则表达式的解析器。他们识别的手势只是用那个字母写的字符串。

所以我们找到了问题的症结所在——为什么不在一开始就设置一个空闲状态I,将手势识别器“启动”到possible 状态?原因是从I 转换到P 需要输入事件。突然,作为被识别手势的字符串变长了一个字母——因此识别出的手势不是我们想要的手势,而是,例如,点击然后手势,或者按下然后手势.

这会改变被识别的手势,从而破坏我们的目的。

【讨论】:

感谢您提供详细的 SM 作品)但是我们的手势怎么会变成“多一个字母”?.. 如果这种状态转换纯粹是技术问题并且可以完全隐藏并且完全在库中完成(甚至在具体的手势识别器之外)。 First touch 开始 - touchesBegan 方法正在执行,如果没有调用 ignoreTouch(因此手势识别器开始跟踪 smth)库在 touchesBegan 执行后将状态设置为可能。没有任何问题,但我们现在有一个重要数据可用(空闲与可能)。 哈!是的,我想它确实花了一点时间。让我问你一个问题:你的空闲状态和可能状态之间的显着区别是什么? 拥有 IDLE 有助于解决手势识别器关系。示例:实现“requireGestureRecognizerToFail”功能。 A(pan) 要求 B(swipe) 失败。但是 B 具有自定义 shouldReceiveTouch 方法的委托,以忽略除特定区域(一次视图)之外的所有触摸。一旦 A 被识别,它应该等待 B 失败,但如果 B 甚至没有跟踪任何触摸(处于 IDLE 状态)——没有必要等待任何东西,A 实际上可以立即切换到 BEGAN 状态。 //你可能会说——只检查 B 轨道的触摸次数。刷卡没问题,点击没用:(IDLE是一个通用的解决方案。

以上是关于UIGestureRecognizer 状态。为啥没有像“空闲”这样的状态?的主要内容,如果未能解决你的问题,请参考以下文章

UIGestureRecognizer

点击按钮时取消 UIGestureRecognizer?

UIGestureRecognizer

手势识别UIGestureRecognizer

UIGestureRecognizer 从头开始​​制作 UISlider

UIGestureRecognizer 目标问题