记录一个小问题(在父视图以外的范围响应子视图事件)
2019-03-08 本文已影响0人
Nulll
关于在父视图外的子视频的响应事件
情况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;
}