iOS hit-Testing 2

 

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
{
          if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) 
          return  nil;
    __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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值