事件的产生和传递:
1.发生触摸事件后,系统会将事件加入到UIApplication管理的队列中
2.UIApplication会将先发生的事件发送给应用程序的主窗口(keyWindow)
3.keyWindow会在视图层次结构中找一个合适的视图,调用视图的touches方法来具体处理事件
4.触摸事件的传递是从父控件传递到子控件,如果父控件不能接收事件(1.userInteractionEnabled =NO,1.hidden=YES,3.alpha=0.0~0.01),那么子控件也不能接收事件
//自己实现系统调用的规则
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
//1.判断是否可以接受事件
if(self.hidden || !self.userInteractionEnabled ||self.alpha<=0.01) return nil;
//2.判断触摸点是否在当前窗体内
if (![self pointInside:point withEvent:event])return nil;
//3.找到当前View的子视图,从后往前遍历,找到最适合处理触摸事件的View
UIView *fitView;
for (int i=(int)(self.subviews.count-1); i>=0; i--) {
UIView *childView =self.subviews[i];
//触摸点是否在childView上
CGPoint childPoint =[self convertPoint:point toView:childView];
fitView =[childView hitTest:childPoint withEvent:event];
if(fitView) return fitView;
}
//4.如果在View的子视图中没找到适合处理事件的View,返回自己
return self;
}
事件传递.png
//自己实现系统调用的规则
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
//1.判断是否可以接受事件
if(self.hidden || !self.userInteractionEnabled ||self.alpha<=0.01) return nil;
//2.判断触摸点是否在当前窗体内
if (![self pointInside:point withEvent:event])return nil;
//3.找到当前View的子视图,从后往前遍历,找到最适合处理触摸事件的View
UIView *fitView;
for (int i=(int)(self.subviews.count-1); i>=0; i--) {
UIView *childView =self.subviews[i];
//触摸点是否在childView上
CGPoint childPoint =[self convertPoint:point toView:childView];
fitView =[childView hitTest:childPoint withEvent:event];
if(fitView) return fitView;
}
//4.如果在View的子视图中没找到适合处理事件的View,返回自己
return self;
}
如何判断上一个响应者
1.如果当前这个view是控制器的view,那么控制器就是上一个响应者
2.如果当前这个view不是控制器view,那么父控件就是上一个响应者