从后往前,就是后添加的子控件,先被遍历
super的内部实现就是图中的4步
点在不在控件上的判断依据,首先点以当前控件的左上角为坐标原点,然后在判断点坐标x值是不是大于该控件的宽度,在判断点坐标y值是不是大于该控件的高度,只要有一个大于,点就不在该控件上
- (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.从后往前遍历自己的子控件,把事件传递给子控件,调用子控件的hitTest,
int count = (int)self.subviews.count;
for (int i = count - 1; i >= 0; i--) {
//获取子控件
UIView *childView = self.subviews[i];
//把当前点的坐标系转换成子控件的坐标系
CGPoint childP = [self convertPoint:point toView:childView];
UIView *fitView = [childView hitTest:childP withEvent:event];
if (fitView) {
return fitView;
}
}
//4.如果子控件没有找到最适合的View,那么自己就是最适合的View.
return self;
}
/** 上面自定义的写法就相当于下面的直接写了 return [super hitTest:point withEvent:event];*/
//什么时候调用:当事件传递给当前View时, 会调用当前Veiw的hitTest方法.
//作用:寻找最适合的View.
//返回值:返回谁,谁就是最适合的view,谁就响应事件,就会调用谁的touches方法
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
//1.判断自己能否接收事件
//2.点在不在自己身上
//3.从后往前遍历自己了的子控件,把事件传递给子控件,调用子控件的hitTest,
//4.如果子控件没有找到最适合的View,那么自己就是最适合的View.
return [super hitTest:point withEvent:event];
}
不去重写touchesBegan方法就是系统的默认做(写)法,交给上一个响应者处理,就是调用上一个响应者的touchesBegan方法
右边多了个父控制器而已
网友评论