事件分发原理:
当触摸事件发生后,整个触摸事件的分发过程如下:
用户点击屏幕—>事件被打包成UIEvent对象—->进入到活动队列—>UIApplication—->window—-(hitTest方法判断哪个视图接收事件)—>rootView—> 子视图
hitTest方法判断哪个视图接收事件的具体步骤如下:
1)遍历当前view的所有subView
2)拿到一个subView,判断一下当前的这个点是否在这个视图内,
3)如果是,就返回当前的view
具体实现代码:
-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
for (UIView *subView in self.subviews) {
if (!subView.userInteractionEnabled) {
return [super hitTest:point withEvent:event];
}
//转换self上的point到subview上
CGPoint subViewPoint = [self convertPoint:point toView:subView];
//判断该点是否在subview中
BOOL result = [subView pointInside:subViewPoint withEvent:event];
if (result) {
//返回的是接收事件的视图
return subView;
}
}
return [super hitTest:point withEvent:event];
}
需要注意的是,以下几点可能会造成事件拦截:
1)userInteractionEnable = NO;
2)hidden = YES;
3)alpha = [0-0.1]范围内
4)点击的point在view范围内,但是超出了父视图的范围,同时view的父类的clipToBounds 属性是NO。