事件的产生与传递
事件是如何产生与传递的?
- 当发生触摸事件的后,系统会将该事件加入到一个由UIApplication管理的时间队列
中,UIApplication会从事件队列中取出最前面的事件,并将这个事件分发下去,以便处理,主
窗口即Window 会在视图层次中找到一个合适的视图来处理触摸事件 - 触摸事件的传递是从父控件传递给子控件的,如果父控件不能接受事件,则里面的所有子控件也不能接收事件
当一个控件不能接受事件时,一般有几种情况
- 不接收用户交互:
userInteractionEnabled = NO
- 当一个控件隐藏时:
Hidden = YES
- 当一个控件为透明时
事件的响应
用户点击屏幕产生的一个触摸事件,经过一系列的传递过程后,会找到一个最适合的视图来处理事件.找到最合适的视图控件后,就会调用控件的
touches
方法来作具体的事件处理.touches
的默认做法是将事件顺着响应者链条向上传递,将事件交给上一个响应者处理
什么是响应者链条?
- 由多个响应者对象连接起来的链条
什么是响应者对象?
- 继承了
UIResponder
的对象
- 继承了
如何去寻找上一个响应者
- 1.如果当前的View是控制器的View,那么控制器就是上一个响应者
- 2.如果当前的View不是控制器的View,那么他的父控件就是上一个响应者
- 3.在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传
递给window对象进行处理 - 4.如果window对象也不处理,则其将事件或消息传递给UIApplication对象
- 5.如果UIApplication也不能处理该事件或消息,则将其丢弃
系统是如何寻找最合适的View*
- 1.先判断自己是否能接收触摸事件
- 2.再判断触摸的当前点在不在自己身上
- 3.如果在自己身上,它会从后往前遍历子控件,遍历出每一个控件后,重启前两步
- 4.如果没有符合条件的子控件,那么自身就是最合适的View
在寻找最合适View的过程中,系统会调用2个方法
1 | // 作用:寻找最适合的View |
那么hitTest: withEvent:方法底层是如何实现的呢?
1 | // 判断自己能否接收事件 |
在开发中或多或少会需要一些特殊的点击,这里有2个小例子供大家参考
- 一个按钮被一个半透明的View部分遮挡,需要点击到按钮的时候,按钮始终响应
- 一个View超出了父视图的范围,需要点击超出范围的View也有响应
1 |
|