美文网首页
响应链&事件传递

响应链&事件传递

作者: 灰溜溜的小王子 | 来源:发表于2020-10-22 16:16 被阅读0次
先上图

再上代码:
重要的是两个方法:

  • -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event ;
  • -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event ;
-(instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor orangeColor];
        self.btn = [UIButton buttonWithType:UIButtonTypeCustom];
        self.btn.frame = CGRectMake(150, 150, 100, 100);
        self.btn.backgroundColor = [UIColor redColor];
        [self addSubview:self.btn];
        [self.btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
        
    }
    return self;
}


-(void)layoutSubviews{
    [super layoutSubviews];
}
-(void)btnClick{
    NSLog(@"btnClick");
    
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    // 如果控件不允许与用用户交互,那么返回nil
    NSLog(@"%@",event);
    if (!self.userInteractionEnabled || [self isHidden] || self.alpha <= 0.01) {
        return nil;
    }
//    NSLog(@"%f----%f",point.x,point.y);
    //判断当前视图是否在点击范围内
    if ([self pointInside:point withEvent:event]) {
        //遍历当前对象的子视图(倒序)
        __block UIView *hit = nil;
        [self.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            //坐标转换,把当前坐标系上的点转换成子控件坐标系上的点
            CGPoint convertPoint = [self convertPoint:point toView:obj];
            //调用子视图的hitTest方法,判断自己的子控件是不是最适合的View
            hit = [obj hitTest:convertPoint withEvent:event];
            //如果找到了就停止遍历
            if (hit)
                *stop = YES;
        }];
        //返回当前的视图对象
        return hit?hit:self;
    }else {
        return nil;
    }
    return nil;
}
// 该方法判断触摸点是否在控件身上,是则返回YES,否则返回NO,point参数必须是方法调用者的坐标系
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGFloat x1 = point.x;
    CGFloat y1 = point.y;
    if ((x1 > 150  && x1 < 250) && (y1 > 150  && y1 < 750)) {
        return YES;
    }else{
        return NO;
    }

}
运行结果
说明:

橙色视图中间添加红色视图;
1.没有两个方法的情况下,在红色视图与橙色交界的范围可响应点击事件;
2.加上如上方两个系统方法处理的条件下,整个红色视图及之外的往下一点儿也可以响应点击事件。
参考:事件传递&响应链

相关文章

网友评论

      本文标题:响应链&事件传递

      本文链接:https://www.haomeiwen.com/subject/xwqpmktx.html