hitTest

熟记响应者链没大毛用,主要还是要从代码层面去理解其过程。从图记起:


hitTest_第1张图片
MJ图
hitTest_第2张图片
点击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;
}

你可能感兴趣的:(hitTest)