熟记响应者链没大毛用,主要还是要从代码层面去理解其过程。从图记起:
MJ图 点击E为例
以点击E为例Hittest步骤如下:
1.触摸点在ViewA内,所以检查SubViewB.C
2.触摸点不在ViewB内,所以检查ViewC的Subviews
3.触摸点不在ViewD内,发生在ViewE内,所以hitTest最终返回ViewE;
PS: 子控件超出父视图之外的部分点击无效也正是基于此
//hitTest内部通过pointInside:withEvent:方法来确定触摸点是否在视图内
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
//透明或隐藏或关闭交互,则返回nil
if (self.alpha <= 0.01 || !self.userInteractionEnabled || self.hidden) {
return nil;
}
BOOL inside = [self pointInside:point withEvent:event];
//触摸点在当前视视图
if (inside) {
//逆向遍历子视图
NSEnumerator *enumerator = [self.subviews reverseObjectEnumerator];
for (UIView *subview in enumerator) {
UIView *hitView = [subview hitTest:point withEvent:event];
if (hitView) {
break;
}
}
if (!hitView) {
hitView = self;
}
return hitView;
} else {
return nil;
}
}
最后附上一个穿透点击事件
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView *view = [super hitTest:point withEvent:event];
if ([view isEqual:self.btn1]) {
return self.btn0;
}
return view;
}
网友评论