iOS事件传递底层实现

1、iOS事件传递主要依靠下面两个方法实现:

  • (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

  • (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

2、-hitText方法的底层实现:

- (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.遍历子控件
    int count = (int)self.subviews.count;
    for (int i = count - 1; i >= 0; i--) {
        UIView *childView = self.subviews[i];
    
        CGPoint childViewP = [self convertPoint:point toView:childView];
    
        UIView *fitView = [childView hitTest:childViewP withEvent:event];
        if (fitView) {
            return fitView;
        }
    }  
     // 如果都没有找到返回本身
     return self;
}

3、利用-hitTest方法来实现点击穿透效果

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (self.canTouch) {
        return hitView;
    }
    if (hitView == self)
    {
        return nil;
    }
    else
    {
        return hitView;
    }
}

只要canTouch属性为NO,点击实现该方法的view时,将穿透该view而到达其下面的view,从而触发下层view的触摸事件。

4、pointInside方法实现穿透效果

23D3D8F9-328B-4E4E-AD3C-77B6C5B208C2.png

图中橙色按钮位于浅绿色view的下面,当点击橙色区域时,点击事件将穿透浅绿色view而响应橙色按钮。

下面给出实现代码:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint btnP = [self convertPoint:point toView:_btn];
BOOL flag = [_btn pointInside:btnP withEvent:event];
if (flag) {
return NO;
}
return [super pointInside:point withEvent:event];

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容