First Responder 和 hitTest 方法之间有啥关系?

Posted

技术标签:

【中文标题】First Responder 和 hitTest 方法之间有啥关系?【英文标题】:Whats the relation between First Responder and hitTest methods?First Responder 和 hitTest 方法之间有什么关系? 【发布时间】:2021-04-02 03:33:12 【问题描述】:

我了解系统如何通过在视图及其子视图上调用以下方法来查找视图处理触摸事件

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

但我不明白第一响应者在这个机制中的作用。

firstResponder是否代表hitTest遍历的起点?

【问题讨论】:

我的知识是,如果 UIView 控件被击中,它将成为第一响应者。就是这样。 【参考方案1】:

我建议完整阅读第一篇文章

Using Responders and the Responder Chain to Handle Events

在 Apple 文档中

Touches, Presses, and Gestures

简答:

    触摸事件直接传递给第一响应者。

当您的应用收到事件时,UIKit 会自动将该事件定向到最合适的响应者对象,即第一响应者。

    第一响应者由命中测试确定。

UIKit 使用基于视图的命中测试来确定触摸事件发生的位置。具体来说,UIKit 将触摸位置与视图层次结构中视图对象的边界进行比较。 UIView 的 hitTest(_:with:) 方法遍历视图层次结构,寻找包含指定触摸的最深子视图,成为触摸事件的第一响应者

    如果第一响应者不处理事件,则事件会从响应者传递到活动响应者链中的响应者。

【讨论】:

谢谢,我已经阅读了文档,但仍然让我感到困惑的是 1. 触摸事件首先传递给 AppDelegate,然后一直递归到屏幕上的最顶层视图使用 HitTest 和 PointInside,对吗?之后,最顶层的视图将是第一响应者。但是第一个链接文档中的图表显示该过程从视图开始。系统如何找到这些视图? 2.何时在链中使用 next(下一个响应者)属性?我在一个演示项目中检查过,将根视图控制器的 next 设置为 nil 不会影响 UIKit 找到我触摸的视图。 来自第一个链接文档“您可以通过覆盖响应者对象的下一个属性来更改响应者链。执行此操作时,下一个响应者就是您返回的对象。” 触摸事件首先传递给第一响应者,而不是 App Delegate。通常,第一响应者是屏幕上最深(最前面)的子视图。 1.发生触摸事件。 2. 自下而上的命中测试 3. 确定第一响应者。 4. 如果不处理触摸,则将事件传递给下一个响应者 5. 下一个响应者,默认情况下,从上到下是它的超级视图,或关联的视图控制器,或窗口,或应用程序。跨度> 【参考方案2】:

它们之间并没有太大的关系,只是命中测试的结果可能导致窗口使命中视图变为firstResponder

firstResponder 是关于键盘事件的,至少在 macOS 上,菜单项操作和命令如cutcopypasteundo 等...

当应用程序从 Window Server 接收到键盘事件时,它会转到 firstResponder。如果它对它不感兴趣,那么它会沿着链向上到达nextResponder,直到耗尽响应者链。在 macOS 上,mainWindowkeyWindow 有相关但独立的概念。它们通常相同,但也可以不同。如果它们不同,则响应者链首先从keyWindow 开始,当该链耗尽时,它会转到mainWindow。然后应用程序会破解它。然后是应用程序的委托。然后,如果它是基于文档的应用程序,则先是文档,然后是文档的委托。

ios 上,我对确切的细节有点模糊,但它是相似的。其实我觉得更简单,因为你没有多个窗口。

另一方面,命中测试是关于视图层次结构的。因此,应用程序会找到命中发生在哪个窗口(在 macOS 上),然后从那里继续向下到它的直接子视图,然后沿着它的子视图等...直到找到被命中的叶视图。

【讨论】:

以上是关于First Responder 和 hitTest 方法之间有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章

LLMNR欺骗工具Responder

ios中事件的响应链(Responder chain)和传递链

Responder探测内网获取域控权限总结

swift #responder

如何通过 Java 解码从 NetConnection.call(methodName, responder, parameter) 发送的消息

Flash AS2 hitTest 无法正常工作