对于IOS设备用户来讲,他们操做设备的方式主要有三种:触摸屏幕、晃动设备、经过遥控设施控制设备。对应的事件类型有如下三种:数组
- 触屏事件(Touch Event)
- 运动事件(Motion Event)
- 远端控制事件(Remote-Control Event)
响应者链(Responder Chain)
- 响应者对象(Responder Object),指的是有响应和处理事件能力的对象。响应者链就是由一系列的响应者对象构成的一个层次结构。
- UIResponder是全部响应对象的基类,在UIResponder类中定义了处理上述 各类事件的接口。咱们熟悉的UIApplication、 UIViewController、UIWindow和全部继承自UIView的UIKit类都直接或间接的继承自UIResponder,因此它们的实例都是能够构成响应者链的响应者对象。
响应者链有如下特色:
- 响应者链一般是由视图(UIView)构成的;
- 一个视图的下一个响应者是它视图控制器(UIViewController)(若是有的话),而后再转给它的父视图(Super View);
- 视图控制器(若是有的话)的下一个响应者为其管理的视图的父视图;
- 单例的窗口(UIWindow)的内容视图将指向窗口自己做为它的下一个响应者须要指出的是,Cocoa Touch应用不像Cocoa应用,它只有一个UIWindow对象,所以整个响应者链要简单一点;
- 单例的应用(UIApplication)是一个响应者链的终点,它的下一个响应者指向nil,以结束整个循环。
点击屏幕时是如何互动的app
- iOS系统检测到手指触摸(Touch)操做时会将其打包成一个UIEvent对象,并放入当前活动Application的事件队列,单例的UIApplication会从事件队列中取出触摸事件并传递给单例的UIWindow来处理,UIWindow对象首先会使用hitTest:withEvent:方法寻找这次Touch操做初始点所在的视图(View),即须要将触摸事件传递给其处理的视图,这个过程称之为hit-test view。
- UIWindow实例对象会首先在它的内容视图上调用hitTest:withEvent:,此方法会在其视图层级结构中的每一个视图上调用pointInside:withEvent:(该方法用来判断点击事件发生的位置是否处于当前视图范围内,以肯定用户是否是点击了当前视图),若是pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操做发生的位置,这个视图也就是要找的hit-test view。
- hitTest:withEvent:方法的处理流程以下:首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;若返回NO,则hitTest:withEvent:返回nil;若返回YES,则向当前视图的全部子视图(subviews)发送hitTest:withEvent:消息,全部子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者所有子视图遍历完毕;若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;如全部子视图都返回非,则hitTest:withEvent:方法返回自身(self)。
事件的传递和响应分两个链:ide
- 传递链:由系统向离用户最近的view传递。UIKit –> active app’s event queue –> window –> root view –>……–>lowest view
- 响应链:由离用户最近的view向系统传递。initial view –> super view –> …..–> view controller –> window –> Application