Responder Chain简析
来源:互联网 发布:河北网络分销商查询 编辑:程序博客网 时间:2024/05/16 09:41
一.responder对象
在iOS系统中,能够响应并处理事件的对象称之为responder object, UIResponder是所有responder对象的基类,在UIResponder类中定义了处理各种事件,包括触摸事件(Touch Event)、运动事件(Motion Event)和远程控制事件(Remote-Control Events)的编程接口,其中处理触摸事件(Touch Event)的编程接口如下:
– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
– touchesCancelled:withEvent:
这四个方法分别处理触摸开始事件,触摸移动事件,触摸终止事件,以及触摸跟踪取消事件。
UIApplication, UIViewController,UIView和所有继承自UIView的UIKit类(包括UIWindow,继承自UIView)都直接或间接的继承自UIResponder,所以它们的实例都是responder object对象,都实现了上述4个方法。UIResponder中的默认实现是什么都不做,但UIKit中UIResponder的直接子类(UIView,UIViewController…)的默认实现是将事件沿着responder chain继续向上传递到下一个responder,即nextResponder。所以在定制UIView子类的上述事件处理方法时,如果需要将事件传递给next responder,可以直接调用super的对应事件处理方法,super的对应方法将事件传递给next responder,即使用
[super touchesBegan:touches withEvent:event];
不建议直接向nextResponder发送消息,这样可能会漏掉父类对这一事件的其他处理。
[self.nextResponder touchesBegan:touches withEvent:event];
另外,在定制UIView子类的事件处理方法时,如果其中一个方法没有调用super的对应方法,则其他方法也需要重写,不使用super的方法,否则事件处理流程会很混乱。
注:UIKit框架的类层次结构图见:UIKit Framework Reference
二.responder chain
上文提到了responder chain,responder chain是一系列连接的responder对象,通过responder对象可以将处理事件的责任传递给下一个,更高级的对象,即当前responder对象的nextResponder。
iOS中responder chain的结构为:
- UIView的nextResponder属性,如果有管理此view的UIViewController对象,则为此UIViewController对象;否则nextResponder即为其superview。
- UIViewController的nextResponder属性为其管理view的superview.
- UIWindow的nextResponder属性为UIApplication对象。
- UIApplication的nextResponder属性为nil。
iOS系统在处理事件时,通过UIApplication对象和每个UIWindow对象的sendEvent:方法将事件分发给具体处理此事件的responder对象(对于触摸事件为hit-test view,其他事件为first responder),当具体处理此事件的responder不处理此事件时,可以通过responder chain交给上一级处理。
- 如果hit-test view或first responder不处理此事件,则将事件传递给其nextResponder处理,若有UIViewController对象则传递给UIViewController,传递给其superView。
- 如果view的viewController也不处理事件,则viewController将事件传递给其管理view的superView。
- 视图层级结构的顶级为UIWindow对象,如果window仍不处理此事件,传递给UIApplication.
- 若UIApplication对象不处理此事件,则事件被丢弃。
三.巧妙利用nextResponder
通过UIViewController的view属性可以访问到其管理的view对象,及此view的所有subviews。但是根据一个view对象,没有直接的方法可以得到管理它的viewController,但我们使用responder chain可以间接的得到,代码如下:
@implementation UIView (ParentController)-(UIViewController*)parentController{ UIResponder *responder = [self nextResponder]; while (responder) {if ([responder isKindOfClass:[UIViewController class]]) {return (UIViewController*)responder;}responder = [responder nextResponder]; } return nil;}@end
参考:
Event Handling Guide for iOS – Responder Objects and the Responder Chain
UIResponder Class Reference
A Bit About the Responder Chain
文章来源:http://blog.csdn.net/chun799/article/details/8223612
- IOS Responder Chain简析
- Responder Chain简析
- Responder Chain简析
- Responder Chain简析
- Responder Chain简析
- Responder Chain简析
- Responder Chain简析
- Responder Chain简析
- responder chain
- iphone的responder chain
- nextResponder与Responder Chain
- The Responder Chain
- The Responder Chain
- iOS Responder Chain
- Responder Objects and the Responder Chain
- Responder Chain(ios事件传递)
- Event Delivery: The Responder Chain
- Responder Chain(ios事件传递)
- linux下使用vim修改jar包zip包内文件内容
- Servlet基础(三) Servlet的多线程同步问题
- 第3周项目4--谁是小偷
- 从头认识多线程-2.11 通过同步代码块证明synchronized标记的是对象锁
- refresh的停车场
- Responder Chain简析
- 华为2016校招机试题(2015年9月) 海大上午场(包含实现代码,运行环境为VS2010)
- spring事物传播特性
- struts2+spring+mybatis整合
- ubuntu双系统安装的一些问题
- WebView加载带中文的网页
- gulp学习总结
- Android Studio 2.0 NDK 开发教程(一)
- 基于bootstrap的网页开发之图片轮播