当我们单击屏幕时,系统会记录该次的触摸事件,添加到Application的事件队列中,然后从keyWindow开始依次向上寻找,结合响应者的pointInside方法和hitTest方法找出处理该触摸事件的View,从而也形成一条事件响应链。
//point是该视图的坐标系上的点
-(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.从后往前遍历自己的子控件,看是否有子控件更适合响应此事件
NSInteger count = self.subviews.count;
for (NSInteger 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];
if (fitView) {
return fitView;
}
}
//4.没有找到比自己更合适的view
return self;
}
应用场景:处理多个UIScrollView的手势冲突,扩大UIButton的响应范围,这些都是通过重写pointInside方法或者hitTest方法来实现的。