响应者链的事件传递过程
一、
hitText方法
1、
hitText方法在
一个事件传递给一个控件的时候,控件就会调用这个方法
2、 hitText 作用 : 寻找到最合适的 view 。
3、hitText方法
1)、 判断窗口能不能处理事件 ? 如果不能,意味着窗口不是最合适的 view ,而且也不会去寻找比自己更合适的 view, 直接返回 nil , 通知 UIApplication ,没有最合适的 view 。
2)、 判断触摸点在不在窗口。
3)、 遍历自己的子控件,寻找有没有比自己更合适的 view。
4)、 如果子控件不接收事件,意味着子控件没有找到最合适的 view, 然后返回 nil , 告诉窗口没有找到更合适的 view, 窗口就知道没有比自己更合适的 view, 就自己处理事件。
// 找最合适的 view
// point 是白色 View 的坐标系上的点
- ( UIView *)hitTest:( CGPoint )point withEvent:( UIEvent *)event
{
// 1. 判断自己能否接收事件
if ( self . userInteractionEnabled == NO || self . hidden == YES || self . alpha <= 0.01 ) return nil ;
// 2. 判断点在不在当前控件上面
if (![ self pointInside :point withEvent :event]) return nil ;
// 3. 去找有没有比自己更合适的 view
// 从后往前遍历自己的子控件
int count = self . subviews . count ;
for ( int i = count - 1 ; i >= 0 ; i--) {
// 获取子控件
UIView *childView = self . subviews [i];
// 转换坐标系
// 把自己坐标系上的点转换成子控件做坐标系上的点
CGPoint childPoint = [ self convertPoint :point toView :childView];
UIView *fitView = [childView hitTest :childPoint withEvent :event];
// 找到最合适的 view
if (fitView) {
return fitView;
}
}
// 没有找到比自己更合适的 view
return self ;
}
2、 hitText 作用 : 寻找到最合适的 view 。
3、hitText方法
1)、 判断窗口能不能处理事件 ? 如果不能,意味着窗口不是最合适的 view ,而且也不会去寻找比自己更合适的 view, 直接返回 nil , 通知 UIApplication ,没有最合适的 view 。
2)、 判断触摸点在不在窗口。
3)、 遍历自己的子控件,寻找有没有比自己更合适的 view。
4)、 如果子控件不接收事件,意味着子控件没有找到最合适的 view, 然后返回 nil , 告诉窗口没有找到更合适的 view, 窗口就知道没有比自己更合适的 view, 就自己处理事件。
// 找最合适的 view
// point 是白色 View 的坐标系上的点
- ( UIView *)hitTest:( CGPoint )point withEvent:( UIEvent *)event
{
// 1. 判断自己能否接收事件
if ( self . userInteractionEnabled == NO || self . hidden == YES || self . alpha <= 0.01 ) return nil ;
// 2. 判断点在不在当前控件上面
if (![ self pointInside :point withEvent :event]) return nil ;
// 3. 去找有没有比自己更合适的 view
// 从后往前遍历自己的子控件
int count = self . subviews . count ;
for ( int i = count - 1 ; i >= 0 ; i--) {
// 获取子控件
UIView *childView = self . subviews [i];
// 转换坐标系
// 把自己坐标系上的点转换成子控件做坐标系上的点
CGPoint childPoint = [ self convertPoint :point toView :childView];
UIView *fitView = [childView hitTest :childPoint withEvent :event];
// 找到最合适的 view
if (fitView) {
return fitView;
}
}
// 没有找到比自己更合适的 view
return self ;
}
/**
* 判断点在不在方法调用者的坐标系上
* point: 是方法调用者的坐标系上的点
*/
- ( BOOL )pointInside:( CGPoint )point withEvent:( UIEvent *)event
{
return NO ;
}
* 判断点在不在方法调用者的坐标系上
* point: 是方法调用者的坐标系上的点
*/
- ( BOOL )pointInside:( CGPoint )point withEvent:( UIEvent *)event
{
return NO ;
}
注意:
1、touch的默认做法:自己不处理,交给上一个响应者。
2、上一个响应者默认是父控件。
二、响应者链的事件传递过程:
1.
如果
view
的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图。
2. 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给 window 对象进行处理
3. 如果 window 对象也不处理,则其将事件或消息传递给 UIApplication 对象
4. 如果 UIApplication 也不能处理该事件或消息,则将其丢弃。
2. 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给 window 对象进行处理
3. 如果 window 对象也不处理,则其将事件或消息传递给 UIApplication 对象
4. 如果 UIApplication 也不能处理该事件或消息,则将其丢弃。