您的位置:首页 > 移动开发 > IOS开发

iOS hit-Testing 2

2016-06-27 15:48 441 查看


1.  强制指定某视图响应触摸事件

-(void)initSubviews
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) / 2);
button.tag = 1000;
button.backgroundColor = [UIColor grayColor];
[button setTitle:@"Button1" forState:UIControlStateNormal];
[self addSubview:button];
[button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
/*
//buttonAction 响应
button.hidden = YES;
button.alpha = 0.001;
//buttonAction 不响应响应
button.userInteractionEnabled = NO;
button.enabled = YES;
*/

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];
button2.frame = CGRectMake(0, CGRectGetHeight(self.frame) / 2, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) / 2);
button2.tag = 1001;
button2.backgroundColor = [UIColor darkGrayColor];
[button2 setTitle:@"Button2" forState:UIControlStateNormal];
[self addSubview:button2];
[button2 addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
}

- (void)buttonAction:(UIButton *)button {
NSLog(@"clicked = %@ ", [button titleForState:UIControlStateNormal]);
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView == [self viewWithTag:1000]) {
return [self viewWithTag:1001];
}
return hitView;
}

2. 在hitTest:withEvent:里筛选返回值,针对指定的对象返回nil

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{

UIView *view = [super hitTest:point withEvent:event];
if([view isEqual:self])
{
return nil;
}
return view;
}

3. 在hitTest:withEvent:里筛选point,判断point在不在指定的范围内

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *view = [super hitTest:point withEvent:event];
if(!CGPathContainsPoint(/*UIBezierPath*/_path.CGPath, NULL, point, NO))
{
return nil;
}
return view;
}自定义不规则图形

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = nil;
UIView *shapView = (UIView *)[self viewWithTag:10086];//不规则图形 (以圆形为例)
BOOL pointInRound = [self touchPointInsideCircle:shapView.center radius:30 targetPoint:point];
if (pointInRound) {
hitView = shapView;
}else {
hitView = self;
}
return hitView;
}

- (BOOL)touchPointInsideCircle:(CGPoint)center radius:(CGFloat)radius targetPoint:(CGPoint)point
{
CGFloat dist = sqrtf((point.x - center.x) * (point.x - center.x) +
(point.y - center.y) * (point.y - center.y));
return (dist <= radius);
}

4. 选定一个节点,遍历他的所有子节点用pointInside:withEvent:判断是否命中,直到找到命中的最低层级的视图,此时我们已经抛弃了系统的hit-testing规则。

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{

UIView *view = [super hitTest:point withEvent:event];
view = [self getActionView:self point:point event:event];
return view;
}

- (UIView *)getActionView:(UIView *)view point:(CGPoint)point event:(UIEvent *)event
{
__block UIView *subView;
//逆序 由层级最低 也就是最上层的子视图开始
[view.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//point 从view 转到 obj中
CGPoint hitPoint = [obj convertPoint:point fromView:view];
if([obj pointInside:hitPoint withEvent:event])//在当前视图范围内
{
if(obj.subviews.count != 0)
{
//如果有子视图 递归
subView = [self getActionView:obj point:hitPoint event:event];

if(!subView)
{
//如果没找到 提交当前视图
subView = obj;
}
}
else
{
subView = obj;
}

*stop = YES;
}
else//不在当前视图范围内
{
if(obj.subviews.count != 0)
{
//如果有子视图 递归
subView = [self getActionView:obj point:hitPoint event:event];
}
}

}];

return subView;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: