在iOS中,当发生事件响应时,必须知道由谁来响应事件。这就是由响应者链来对事件进行响应,所有事件响应的类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获得响应事件消息的机会。当发生事件时,事件首先被发送给第一响应者,第一响应者往往是事件发生的视图,也就是用户触摸屏幕的地方。事件将沿着响应者链一直向下传递,直到被接受并作出处理。
一般来说,第一响应者是个视图对象或者其子类对象,当其被触摸后事件交由他处理,如果他不处理,事件就会被传递给它的视图控制器对象ViewController(如果存在),然后是他的父视图(superview)对象(如果存在),以此类推,直到顶层视图。接下来会沿着顶层视图(top view)到窗口(UIWindow对象),再到程序(UIApplication对象)。如果整个过程都没有响应这个事件,该事件就被丢弃。一般情况下,在响应链中只要有对象处理事件,事件就停止传递。
一个典型的响应路线如下:
First Responder-->The Window-->The Application-->App Delegate.
有了以上的基础,我们来谈谈事件。iOS中事件分为三类,触摸屏幕、晃动设备、远程控制设备。对应的事件类型有以下三种:
(1)触屏时间(Touch Event);
(2)运动事件(Motion Event);
(3)远程控制事件(Remote-Control Event);
现在我们以触摸事件为例,来深入了解一下响应者链(Responder Chain).
响应者对象(Responder Object),指的是有响应和处理事件能力的对象。响应者链就是一系列的响应者对象构成的一个层次结构。UIResponder是所有响应对象的基类,在UIResponder类中定义了处理上述各种事件的接口。我们熟悉的UIApplication,UIViewController,UIWindow和所有继承自UIView的UIKit类都直接或者间接继承自UIResponder,所以他们的实例都是可以构成响应者链的响应者对象。如下图所示:
从上图可以看到,响应者链有以下特点:
(1)响应者链通常是由视图(UIView)构成的;
(2)一个视图的下一个响应者是他的视图控制器(UIViewController)(如果有的话),然后再传给它的父视图(SuperView)。
(3)视图控制器(如果有的话)的下一个响应者为其管理的视图的父视图。
(4)单例的窗口(UiWindow)的内容视图将指向窗口本身作为它的下一个响应者。
(5)单例的应用(UIApplication)是一个响应者的终点。它的下一个响应者指向nil,以结束整个循环。
然后再来了解下事件分发(Event Delivery):
第一响应者(First Responder)指的是当前接受触摸的响应者对象(通常是一个UIView对象),即表示当前该对象正在与用户交互,它是响应者链的开端。整个响应者链和事件分发的使命都是找出第一响应者。UIWindow对象以消息的形式将事件发送给第一响应者,使其有机会首先处理事件。如果第一响应者没有进行处理,系统就将事件(通过消息)传递给响应链中的下一个响应者,看他是否能够处理。
现在我用几句话来简单说明下什么是响应者链条:
(1)响应者链是由多个响应者对象链接起来的队列;
(2)响应者对象是指能够处理事件的对象,也就是继承自UIResponder的对象;
(3)使用响应者链条,能够让一条链上的多个对象对同一事件作出响应;
(4)消息在响应者链上传递也就是想找到下一个响应的对象(nextResponder);
这里我们要注意到一个问题,对于消息事件的管理,我们使用的是队列,而不是栈,因为我们要保证先产生的事件先处理,也就是先进先出。
github主页:https://github.com/chenyufeng1991 。欢迎大家访问!