Day1-UIKit事件传递机制 & Responder Chain
UIKit 事件传递机制 & Responder Chain
一、事件类型
UIKit 中主要的事件类型包括:
- 触摸事件(Touch Events):如 tap、swipe、pinch 等。
- 运动事件(Motion Events):如摇动设备。
- 远程控制事件(Remote-Control Events):如耳机控制、CarPlay。
- 按键事件(Press Events)(仅限 tvOS 或支持硬件键盘时的 iOS)。
二、事件传递流程
- 事件产生: - 事件由硬件(屏幕、传感器等)检测后交给系统。
- iOS 将事件加入到主线程的 UIApplication对象中进行分发。
 
- 事件分发路径: - UIApplication→- UIWindow→- UIView
 
- 命中测试(Hit-Testing): - 从根视图(window 的 rootView)开始递归查找目标视图。
- 使用两个方法:- point(inside:with:)
- hitTest(_:with:)
 
- 最终找到最合适的视图接收触摸事件。
 
三、Responder Chain(响应者链)
1. 什么是 Responder Chain?
Responder Chain 是一条事件响应链,用来处理视图无法响应的事件。
2. Responder Chain 构成
一个 UIResponder 对象(如 UIView、UIViewController)可以传递事件给其上层响应者:
UIView → UIViewController → UIWindow → UIApplication → AppDelegate
如果某个对象无法处理事件,它会把事件传递给下一个响应者。
3. UIResponder 方法
| 方法名 | 说明 | 
|---|---|
| touchesBegan(_:with:) | 开始触摸 | 
| touchesMoved(_:with:) | 触摸移动 | 
| touchesEnded(_:with:) | 触摸结束 | 
| touchesCancelled(_:with:) | 触摸被取消 | 
还可以通过 canBecomeFirstResponder 和 becomeFirstResponder() 控制焦点。
四、自定义事件传递(常见场景)
1. UIView 不响应事件
可能是因为以下原因:
- isUserInteractionEnabled = false
- alpha < 0.01
- hidden = true
2. 自定义控件事件传递
可重写以下方法:
- hitTest(_:with:):决定谁是事件的最终响应者。
- point(inside:with:):判断点是否在当前视图内。
五、Responder Chain 应用场景
- 控件事件传递:如 UIButton 点击事件向上传递。
- 菜单处理:如复制粘贴菜单响应。
- 键盘响应管理。
- 自定义事件路由(target-action 无法处理时)。
六、调试技巧
- 使用 View Debugger 检查视图层级。
- 打断点调试 hitTest和touchesBegan。
- 查看 next属性追踪 Responder Chain。
七、总结
- UIKit 事件从 UIApplication 开始,经过 UIWindow 最终传递给具体的 UIView。
- Responder Chain 是事件冒泡机制的实现,支持事件的多级处理。
- 通过合理利用 hitTest:和Responder Chain,可以实现复杂交互需求。