先来大致说一下原理:
1、第一步,定位点击了哪个view
一个应用,有那么多的界面元素,应用怎么就知道我点击了哪里呢?
层层叠加的view,它是叠加在它的父view的,so,追溯父view到尽头,会有一个根。这样会形成一个树状结构,也就是我们的图层树。
从根向它的子结点,逐个询问“这个点击是不是落到你这里”?如果是,询问这个结点的子结点,这样遍历下去,找到最顶的的子结点,也就是叠加到最顶端的view。
2、第二步,作出反馈
找到了具体点击哪个view了,那么下面让view来作出反馈响应,
如果能,这个流程就结束了。
如果不能,view是叠加在它的父view上的,不能响应,就说明view只是作为一个单纯的图层,从用户角度,那么这个点击,应该是落在它的父view上面。
以此类推,向父view一直找,找到能作出反馈的,处理掉,一个点击事件就结束。
如何实现
上面的步骤一,称为事件分发。询问的这个动作,通过UIView的-hitTest:withEvent方法来实现,方法内部通过调用-pointInside:withEvent:判断触点是否发生在该view内部并递归调用,直到找到最终的subview。
步骤二,涉及到一个叫响应者链。也就依次找父view去处理的这个链条。我们view不能处理的话,会交由它的viewController去处理。
完整流程:
1、用户触发事件
2、UIkit框架将事件封装成UIEvent,把event加入到当前活动的app的事件队列中
3、下一次main runloop时,app把event从事件队列中取出,把event传递给key window对象
4、事件分发
5、通过响应者链,处理事件
6、找不到响应的,丢弃,不作任何处理
官图了解一下:
网友评论