触摸事件传递和响应原理
传递流程总览
一次触摸从系统层进入应用后,会被封装成 UIEvent,然后按窗口和视图层级分发。核心点在两个方法:
hitTest:withEvent::决定最终命中视图pointInside:withEvent::判断触点是否在视图有效区域
为什么“看得见却点不到”
常见原因:
- 触点在视图 frame 外
- 父视图禁用交互
- 上层透明视图拦截
- 手势识别器提前消费
事件响应优先级
通常先命中具体 view,再进入该 view 的响应方法。如果该 view 不处理,再沿响应链向上。
这意味着父视图可作为兜底层,但不应过度承载子视图逻辑。
自定义命中区域
按钮可通过重写 pointInside 扩大点击热区,提高可用性。实现时要避免覆盖相邻控件热点。
实战建议
- 列表场景优先保证 cell 点击路径清晰。
- 手势与点击并存时实现手势代理,精细控制是否同时识别。
- 遇到复杂冲突先画视图层级图,再做代码调整。
总结
触摸问题的本质是“谁先拿到事件、谁决定是否继续传递”。只要把命中规则和响应链理清,交互故障通常都能快速修复。