【学习笔记】响应者链条
自学iOS有一两个月了,一直没有好好整理学习笔记,打算今天开始慢慢补上,就当是复习和补缺补漏吧。
iOS的事件大致分为三种:触摸事件、加速计事件、远程控制事件
首先要理解以下几个概念:
一、响应者对象:
在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象”。
UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件。
二、UIResponder处理事件的主要方法
触摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
加速计事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event; - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event; - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;
三、UITouch
用户同时触摸的手指,每一根就代表一个UITouch对象,它保存着跟手指相关的信息,比如触摸的位置、时间、阶段。
当手指移动(move)时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置。
当手指离开(end)屏幕时,系统会销毁相应的UITouch对象.
四、UIEvent
触摸事件发生,必须会产生一个UIEvent对象,称为事件对象,记录事件产生的时刻和类型。
五、首先处理事件的响应者
发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中。
UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)
主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的第一步
找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理
touchesBegan…
touchesMoved…
touchedEnded…
下面是老师上课的PPT示例,说的很明白。
UIView不接收触摸事件的三种情况
1.alpha= 0.0 ~ 0.01
2.hidden属性=YES
3.userInteractionEnabled=YES
注意:UIImageView的userInteractionEnabled默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的
六、响应者链条
合适的控件调用touches方法后,会默认地将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理。
寻找上一个响应者的过程,看起来是寻找首要合适控件的逆过程。
当前响应者的touches方法中如果调用[super touches],就会对用上一个响应者touches方法,同时可以将UITouch对象和UIEvent对象向上传递。
这样就能够将一次触摸事件的事件对象和触摸对象的信息传递给多个响应者。
问题:上一个响应者(nextResponder)是谁?
判断步骤:
1>如果当前的view是控制器的view,控制器就是上一个响应者
2>如果当前的view不是控制器的view,那么父控件就是上一个响应者
3>如果当前响应者是控制器,那么上一个响应者是UIWindow;如果UIWindow也不处理,就再往上传给UIApplication
4>如果UIApplication也不处理,那么这条消息就被会废弃
七、触摸事件处理过程
1.用户触摸后,系统先将事件对象(event)由上往下传递(父控件传给子控件),找到最合适的控件来处理事件(递归查找当前控件的最适合子控件)
2.调用合适控件的touches相关方法
3.如果调用了super的touches相关方法,就会将事件顺着响应者链条往上传递,传给上一个响应者
4.接着就会调用上一个响应者的touches方法
5.只要当前响应者的touches方法中调用了super的touches方法,还会继续往上递归调用,直到不再调用super的touches方法
八、补充面试题:什么是响应者链条?
以下几个点是李明杰老师给的参考回答,可学习借鉴:
1>响应者链条是由多个响应者对象连接起来的链条
2>响应者对象是指能够处理事件的对象,即继承UIResponder的对象
3>利用响应者链条,能让多个控件处理同一个触摸事件
4>简要叙述响应者链条的往上传递,找到上一个响应者(nextResponder)