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
,可以实现复杂交互需求。