- hitTest: withEvent: 的浅见(踩过的一个坑)

  1. 话说UIView不接收触摸事件的三种情况
- 不接收用户交互: userInteractionEnabled = NO
- 隐藏: hidden = YES
- 透明: alpha = 0.0 ~ 0.01
  1. 由此我们在使用- hitTest: withEvent:方法时,很容易以为上述情况下的View是不会触发此方法。然而并不是这样。
  1. 这样在重写该方法时,会导致在特俗情况下得到的并不是我们真正需要的View
  1. 如:让一个tableViewCell上的一个的subView来接收tap手势,就可能会出现返回并不是这个cell上的subView,而是缓存池中的一个cell的subView
  1. 正确写法
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    // 判断当前控件能否接收事件(过滤不满足条件的View)
    if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) {
        // 注意:尽管不满足接收事件的条件,但是系统还是回调用该方法。所以此处需要自行屏蔽
        // 此处如果不实现的影响:会小概率出现返回缓存池中的cell,并不是真正需要的cell
        return [super hitTest:point withEvent:event];
    }
    
    CGRect rect = self.subView.frame;
    if(CGRectContainsPoint(rect, point)){
        return self.subView;
    }
    return [super hitTest:point withEvent:event];
}

// 或(推荐)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    // 先由系统过滤
    UIView *hitView = [super hitTest:point withEvent:event];
    
    // 条件根据情况而定
    if([hitView isEqual:self]) {
        CGRect rect = self.subView.frame;
        if(CGRectContainsPoint(rect, point)){
         hitView = self.subView;
        }
    }
    
    return hitView;
}

你可能感兴趣的:(- hitTest: withEvent: 的浅见(踩过的一个坑))