Using Responders and the Responder Chain to Handle Events

App接收和處理事件方式:

App接收和處理事件是用responder objects(p.s. instance of the UIResponder class)。App接收到事件後,UIKit會自動把事件傳給最適當的responder object,其稱為first responder。如果first responder object未處理此事件,則未處理事件會在responder chain中依序往下傳遞。

Responder objects例子:

UIView、UIViewController、UIApplication

Responder chain:

使用者互動事件的傳遞路徑(p.s. 可接收互動事件的object皆為UIResponder object)。
Note: UIResponder object可以動態設定下一層的UIResponder object。

Responder chain例子:

Responder chain例子(參考自Apple documentation)

官方說明:

If the text field does not handle an event, UIKit sends the event to the text field’s parent UIView object, followed by the root view of the window. From the root view, the responder chain diverts to the owning view controller before directing the event to the window. If the window cannot handle the event, UIKit delivers the event to the UIApplication object, and possibly to the app delegate if that object is an instance of UIResponder and not already part of the responder chain.

如何決定Event’s First Responder:

根據Event type,不同Event type決定First responder方式如下:

Event typeFirst responder
Touch eventsThe view in which the touch occurred.
Press eventsThe object that has focus.
Shake-motion eventsThe object that you (or UIKit) designate.
Remote-control eventsThe object that you (or UIKit) designate.
Editing menu messagesThe object that you (or UIKit) designate.

Touch Event如何決定Responder chain:

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.

簡單來說,一個touch event發生後,會透過UIView的hitTest method來決定touch location在哪些view objects的bound內(p.s. 這些view objects構成responder chain),之後再由responder chain由上往下,看哪個view object可以處理這次的touch event。

Note:

Hit-test: Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point. (官方說明)

以上面的官方responder chain為例來說明:

使用者點擊在UITextfield上,則hittest method觸發順序為UIApplication -> UIWindow -> UIViewController -> UIView -> UIView -> UITextField。則Responder chain(由上到下)的順序為UITextField -> UIView -> UIView -> UIViewController -> UIWindow -> UIApplication

Ref:

https://zhongwei0717.medium.com/%E4%B8%8D%E8%A6%81%E5%B7%B2%E8%AE%80%E4%B8%8D%E5%9B%9E-ios-%E7%9A%84-responder-chain-cc836d7c9e61

https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/using_responders_and_the_responder_chain_to_handle_events