美文网首页
记录一个小问题(在父视图以外的范围响应子视图事件)

记录一个小问题(在父视图以外的范围响应子视图事件)

作者: Nulll | 来源:发表于2019-03-08 19:16 被阅读0次

关于在父视图外的子视频的响应事件

情况1: 屏幕快照 2019-03-08 下午6.55.39.png

如图所示,红色视图为UIView,绿色视图为BIButton,现在需要button的所有范围都可以相应点击事件。

这种情况需要单独继承出一个UIView,并且重写pointInside 这个方法。

/// 下面的代码时TestView的内部实现。当你需要整个button都可以响应点击事件,只需要 -pointInside: withEvent: 将这个方法返回YES 就可以了。

@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) { 
        self.backgroundColor = [UIColor redColor]; 
    }
    return self;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { 
    return YES;
}

@end

但是这样会导致这个view在父视图的范围内都可以实现响应,即在红色的view上添加手势,点击白色区域也可以有响应事件。

如果要做到只有红色和绿色区域的响应事件,

// 下面的为红色视图的绿色视图的布局情况。
    TestView *vv = [[TestView alloc] initWithFrame:CGRectMake(60, 160, 200, 60)];
    [self.view addSubview:vv];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
    [vv addGestureRecognizer:tap];
    
    TestButton *btn = [[TestButton alloc] initWithFrame:CGRectMake(-30, -30, 60, 60)];
    [vv addSubview:btn];
    [btn addTarget:self action:@selector(click) forControlEvents:(UIControlEventTouchUpInside)];
    

然后将方法 -pointInside: withEvent: 修改为如下即可。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
 
    CGRect btnRect = CGRectMake(-30, -30, 60, 60);
    if (CGRectContainsPoint(btnRect, point)) {
        return YES;
    }
    /// 如果这里有多个子视图需要处理就多写几个

    CGRect selfRect = self.bounds;
    if (CGRectContainsPoint(selfRect, point)) {
        return YES;
    }
    
    return NO;
}

到此为止,完美解决。

情况2: UIslider的响应拖动范围扩大。

///继承UIslider,并且重写如下方法既可以;
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {
    
    CGRect superRect = [super thumbRectForBounds:bounds trackRect:rect value:value];
    
    CGRect result = CGRectInset (superRect, -30 ,-30);
    
    return result;
}

// 如果UISlider 的frame 范围太小,那么再重写 -pointInside: withEvent: 方法既可以
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
  /// 至于这里需要多少的范围,和上面一样,定义几个frame 就好了。
    return YES;
}

相关文章

网友评论

      本文标题:记录一个小问题(在父视图以外的范围响应子视图事件)

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