首页 » iOS编程(第4版) » iOS编程(第4版)全文在线阅读

《iOS编程(第4版)》12.8 深入学习:响应对象链

关灯直达底部

第7章已简单介绍过UIResponder和第一响应对象。UIResponder对象可以接收触摸事件,而UIView是典型的UIResponder子类。除了UIView,还有很多其他的UIResponder子类,其中包括UIViewController、UIApplication和UIWindow。UIViewController不是视图对象,既不能触摸也无法显示,为什么也是UIResponder子类?这是因为虽然不能向UIViewController对象直接发送触摸事件,但是该对象能够通过响应对象链接收事件。

UIResponder对象拥有一个名为nextResponder的指针,相关的UIResponder对象可以通过该指针组成一个响应对象链(见图12-5)。当UIView对象属于某个UIViewController对象时,其nextResponder指针就会指向包含该视图的UIViewController对象。当UIView对象不属于任何UIViewController对象时,其nextResponder指针就会指向该视图的父视图。UIViewController对象的nextResponder通常会指向其视图的父视图。最顶层的父视图是UIWindow对象,而UIWindow对象的nextResponder指向的是UIApplication单例。

图12-5 响应对象链

如果UIResponder对象没有处理传给它的事件,会发生什么?该对象会将未处理的消息转发给自己的nextResponder。这也是touchesBegan:withEvent:这类方法的默认实现。因此,如果没有为某个UIResponder对象覆盖特定的事件处理方法,那么该对象的nextResponder会尝试处理相应的触摸事件。最终,该事件会传递给UIApplication(响应对象链的最后一个对象),如果UIApplication也无法对其处理,系统就会丢弃该事件。

除了由UIResponder对象向nextResponder转发消息,也可以直接向nextResponder发送消息。假设有一个正在跟踪触摸事件的视图,当该视图发生连按事件时,需要由该视图的nextResponder来处理这个事件。相应的代码如下:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];

if (touch.tapCount == 2) {

[[self nextResponder] touchesBegan:touches withEvent:event];

return;

}

……继续处理非连按触摸事件

}