First Responder 和 hitTest 方法之间的关系是什么?

Whats the relation between First Responder and hitTest methods?

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

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

但是我不明白first responder在这个机制中的作用

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

他们之间没有太大关系,除了命中测试的结果可能导致window使命中视图变成firstResponder .

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

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

关于 iOS,我对确切的细节有点模糊,但它是相似的。其实我觉得更简单,因为你没有多个 windows.

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

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

Using Responders and the Responder Chain to Handle Events

在 Apple 文档中

Touches, Presses, and Gestures

简答:

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

When your app receives an event, UIKit automatically directs that event to the most appropriate responder object, known as the first responder.

  1. 第一响应者通过命中测试确定。

UIKit uses view-based hit-testing to determine where touch events occur. Specifically, UIKit compares the touch location to the bounds of view objects in the view hierarchy. The hitTest(_:with:) method of UIView traverses the view hierarchy, looking for the deepest subview that contains the specified touch, which becomes the first responder for the touch event.

  1. 如果第一响应者不处理事件,则事件将在活动响应者链中从响应者传递到响应者。