目录
概念
响应者链(即响应链)
由当前页节点向父节点以上所延伸出的一条链(view->superView…->VC->Window->Appliction)
节点(即响应者对象:有响应和处理事件能力的对象)继承UIResponder
一个节点可有多个子节点,一个子节点只有一个父节点
当前页节点:手指触摸到的控件
[button nextResponder] : 返回下一个响应者(即父节点)
[button allTargets] : 返回所有响应者
触摸操作响应过程
iOS系统检测到触摸操作时,会将触摸事件打包成UIEvent对象并放入当前UIApplication的事件队列中。UIApplication将触摸事件从事件队列取出,并传递给UIWindow。UIWindow通过hitTest:withEvent方法找到此次Touch操作的初始点所在的控件(当前节点)。具体过程如下:
1、寻找到叶结点
UIWindow首先调用根视图(当前视图)的pointInside:withEvent:判断触摸点是否在根视图内;
若不在,则hitTest:withEvent:返回nil;
若在,则操作X:向当前视图的所有子视图(subviews,index越大越先被访问)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图(即从subviews数组的末尾向前遍历)。
若所有子视图都返回空对象, 则hitTest:withEvent:方法返回当前视图自身(self) 即叶节点。hitTest:withEvent:方法返回此对象,处理结束。
若子视图还有子辈视图且触摸点在该子视图(当前视图)内则跳到操作X。直到有子视图(没有子辈视图)返回非空对象 即叶节点。 hitTest:withEvent:方法返回此对象,处理结束。
2、叶节点可以选择处理/忽略响应,忽略则交给父节点响应,处理则可选择是否向父节点传递事件(默认:停止分发) 。如果最后交给UIApplication也没处理该事件,则忽略该事件。
hitTest:withEvent:会忽略:
1、隐藏(hidden=YES)的视图
2、禁止用户操作(userInteractionEnabled=YES)的视图
3、以及alpha级别小于0.01(alpha<0.01)的视图
4、子视图超过父视图的区域(且父视图的clipsToBounds 属性为NO
Hit-Test的应用
1. 扩大按钮的点击范围
2. 重叠时希望下方View响应事件
3. 在SV滚动视图(frame)的范围外使手势有效
网友评论