响应者链即Responder Chain,是有一定层级关系的连接在一起的响应者对象集合。
响应者对象,即能够接受和处理事件的对象,在ios系统中,所有的响应者对象都是直接或间接继承自UIResponder类。
比较熟悉的类有UIApplication,UIWindow,UIViewController,UIView等。我们都知道,CALayer不能添加或处理事件,就是因为
CALayer不是继承自UIResponder类。
响应链执行的过程,就是寻找第一响应者对象的过程。这个过程大概是这样的:
1、设备产生触摸、加速器等事件后,系统把事件封装成UIEvent对象,并通过RunLoop添加到UIApplication持有的事件队列中
2、UIApplication取出事件,并分发给UIWindow
3、然后依次在UIWindow的子类中调用方法-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
4、hitTest方法会调用方法-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 来判断操作区域是否在当前视图中
5、hitTest方法会过滤掉hidden属性为YES、userInteractionEnabled属性为NO, alpha值小于0.01的子视图
6、UIWindow的子类会在自己的子类中递归调用hitTest方法,直到该方法返回最后一个非空的UIView对象,这个对象就是第一响应者。
而事件的响应过程,和响应链的执行过程刚好是相反的。过程大致如下:
1、判断第一响应者能否处理事件,如果能,则直接处理。
2、如果不能,则通过调用nextResponder方法,顺着响应者链寻找下一个响应者。
3、如果下一个响应者也不能处理该事件,则顺着响应链继续往下寻找。
4、直到下一个响应者对象为UIApplicationDelegate对象时,如果UIApplicationDelegate不能处理该事件,那么系统就会结束查找,并抛弃该事件。
响应链除了帮我们更深刻的理解界面交互的理论基础,还有以下用途:
1、查找UIView对应的UIViewController
2、扩大视图响应或者点击区域(通过重写pointInside方法)
3、帮助我们排除视图点击不响应的问题
网友评论