事件传递
在iOS中,事件一般包括三种:触摸事件、加速器事件、远程事件
我们以触摸事件为例。
在iOS中只有继承了UIResponder响应者对象的对象才能够响应事件。主要包括UIApplication、UIview、UIwindow。
事件传递过程
简单的描述就是:屏幕被触摸——>将触摸事件加入UIApplication控制的一个队列中——>取出队列第一个触摸事件,传递给window——>寻找最合适的view。
寻找最适合的响应触摸事件的view
window会在视图层次中,从上往下寻找最适合的view,首先判断父控件,然后遍历父控件的子控件,直到找到最适合的view。
具体过程:
(1)主窗口接收了分发的时间,判断自己能不能接收事件,如果可以,判断触摸点在不在自己身上,如果在,进入步骤2;
(2)遍历自己的子控件;每遍历一个子控件,完成两步:第一是子控件能不能接收事件,第二是触摸点在不在子控件上。
(3)如此循环,找到最终的view
寻找最合适的view的底层实现
关系到两个函数:
(1)hitTest:withEvent
传递事件给一个对象,就会调用这个对象的hitTest:withevent方法
(2)pointIside
上面的hitTest:withEvent方法会调用pointInside方法,判断触摸点是否在本空间之内。
总的来说:事件传递机制的过程如下:
触摸事件——>UIApplication控制的队列——>第一个触摸事件传递给window,window判断自己能不能响应事件,触摸点是都在window内部,也就是调用 [window hittest:withEvent]——>寻找更适合的view[subview hitTest:event]——>直到返回更为适合的view
事件响应
找到最适合的view之后,就将事件传递给了这个view,然后开始事件响应
需要明白一个概念,就是响应者链条:
我们知道视图是有层次结构等,一般都是Application->window->controller->view A->view A d的子控件。。。。。。
如下图:
首先要明白事件的传递是从上到下,也就是大体上从父控件到子控件,而响应过程却是相反的,在传递过程中,我们找到了最适合的view,那么响应过程,我们就要从这个 view开始往上传递。
那么,我们找到最适合的响应者,就行了呀,就可以响应触摸事件啦,为啥我们还要响应者链呢,主要的目的就是让一个事件被多个响应者所响应。
响应过程
(1)如果当前的view是控制器的view,那么上一个响应者就是控制器;
(2)当前view不是控制器的view,那么就上一个响应者就是父控件
(3)在试图层次的顶层响应者也不能处理事件,那就交给window处理;
(4)window不能处理,就交给UIApplication处理
(5)都不能处理,就丢弃