当我们在手机上点击、滑动屏幕等操作进入到相应的页面,手机是如何区分相应指令并响应的呢?其中又是经历了怎样的过程呢?
1. 什么是事件链?
如下图所示,点击屏幕时,首先UIApplication对象先收到该点击事件,再依次传递给它上面的所有子view,直到传递到最上层,即UIApplication——>UIWindow——>RootViewController——>View——>Button,即传递链。而反之Button——>View——>RootViewController——>UIWindow——>UIApplication则为响应链。简单总结,事件链包含传递链和响应链,事件通过传递链传递下去,通过响应链找到相应的UIResponse。
2. 传递链:由系统向离用户最近的view传递,如上图所示。
在点击屏幕时系统会将点击事件加入到UIApplication管理的事件队列中;
而UIApplication会从消息队列中取出该事件传递给UIWindow对象;
在UIWindow中调用方法hitTest:withEvent:返回最终相应的view;
在hitTest:withEvent:方法中调用pointInside:withEvent:来判断当前点击的点是否在UIWindow内部,如若返回yes,则倒序遍历其子视图找到最终响应的子view;
如果最终返回一个view,那么即为最终响应view并结束事件传递,如果无值返回则将UIWindow作为响应者。
其中核心方法如下,
方法hitTest:withEvent:用来找到最终响应事件的view。
方法pointInside,用来判断点击的位置是否在视图范围内。
以下情况为UIView不接受事件处理的case:
3. 响应链:由离用户最近的view向系统传递。如下所示,
若view的vc存在,则将该事件传递给其vc响应;如若不存在,则传递给其父视图;
若view的最顶层不能处理事件,则传递给UIWindow进行处理;
若UIWindow不能处理,则传递给UIApplication;
若UIApplication不能处理,则将该事件丢弃。
4.示例代码如下