响应者对象是可以响应事件并对其进行处理的对象。UIResponder
是所有响应者对象的基类,它不仅为事件处理,而且也为常见的响应者行为定义编程接口。UIApplication
、UIView
、和所有从UIView
派生出来的UIKit类(包括UIWindow
)都直接或间接地继承自UIResponder
类。
第一响应者是应用程序中当前负责接收触摸事件的响应者对象(通常是一个UIView
对象)。UIWindow
对象以消息的形式将事件发送给第一响应者,使其有机会首先处理事件。如果第一响应者没有进行处理,系统就将事件(通过消息)传递给响应者链中的下一个响应者,看看它是否可以进行处理。
响应者链是一系列链接在一起的响应者对象,它允许响应者对象将处理事件的责任传递给其它更高级别的对象。随着应用程序寻找能够处理事件的对象,事件就在响应者链中向上传递。响应者链由一系列“下一个响应者”组成,其顺序如下:
-
第一响应者将事件传递给它的视图控制器(如果有的话),然后是它的父视图。
-
类似地,视图层次中的每个后续视图都首先传递给它的视图控制器(如果有的话),然后是它的父视图。
- 最上层的容器视图将事件传递给
UIWindow
对象。 -
UIWindow
对象将事件传递给UIApplication
单件对象。
如果应用程序找不到能够处理事件的响应者对象,则丢弃该事件。
响应者链中的所有响应者对象都可以实现UIResponder
的某个事件处理方法,因此也都可以接收事件消息。但是,它们可能不愿处理或只是部分处理某些事件。如果是那样的话,它们可以将事件消息转送给下一个响应者,方法大致如下:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { |
UITouch* touch = [touches anyObject]; |
NSUInteger numTaps = [touch tapCount]; |
if (numTaps < 2) { |
[self.nextResponder touchesBegan:touches withEvent:event]; |
} else { |
[self handleDoubleTap:touch]; |
} |
} |
请注意:如果一个响应者对象将一个多点触摸序列的初始阶段的事件处理消息转发给下一个响应者(在touchesBegan:withEvent:
方法中), 就应该同样转发该序列的其它事件处理消息。
动作消息的处理也使用响应者链。当用户对诸如按键或分页控件这样的UIControl
对象进行操作时,控件对象(如果正确配置的话)会向目标对象发送动作消息。但是,如果目标对象被指定为nil
,应用程序就会像处理事件消息那样,把该动作消息路由给第一响应者。如果第一响应者没有进行处理,再发送给其下一个响应者,以此类推,将消息沿着响应者链向上传递。