iOS HitTest 机制

当用户触摸(Touch)屏幕进行交互时,系统首先要找到响应者(Responder)。系统检测到手指触摸(Touch)操作的时候,将Touch
以UIEvent 的方式加入到UIApplication 事件队列中去。UIApplication 从事件队列中取出最新的触摸事件进行分发传递到UIWindow 进行处理
.UIWindow 会通过hit Test:WithEvent 方法寻找触碰点所在的视图。这个过程称之为hit-test view。

顺序如下
UIApplication --》UIWindow—》Root view —> subview

在顶级视图(Root View) 上调用pointInside:withEvent 方法判断触摸点是否在当前视图内;
如果返回NO,那么hitTest:withEvent 返回nil
如果返回YES,那么会向当前视图的所有子视图发送hitTest:WithEvent 消息,所有子视图的遍历顺序是从最顶层视图一直到最底层视图,即从subviews 数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕。

如果有subview 的hitTest:WithEvent 返回非空对象则返回此对象,处理结束。
此过程,子视图也是根据pointInSide:WithEvent 返回值来确定是返回空还是当前子视图对象的。并且这个过程如果子视图的hidden=yes
userInteractionEnabled=NO或者alpha小于0.1都会并忽略。
如果所有subview 遍历结束仍然没有返回非空对象,则hitTest:WithEvent 返回self
系统就是这样通过hit test 找到触碰到的视图(initial View)进行响应。

    // 此方法就是寻找最为合适的响应的空间
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
     
        super.hitTest(point, with: event);
        
        // 1 UIView不接收触摸事件的三种情况:
        
//        * userInteractionEnabled = NO
//            * hidden = YES
//            * lpha = 0.0 ~ 0.01
        
        if self.isUserInteractionEnabled == false || self.alpha <= 0.1 || self.isHidden == true {
            
            return nil;
        }
        
        //  2 判断当前的点是否在此控件上面
        if self.point(inside: point, with: event) == false {
            return nil;
        }
        
        
        // 3 以上条件都满足 去遍历自己的子空间
        let count = self.subviews.count;
        
        for view in self.subviews {
            
            // 转为目标控件的点
            let current_point = self.convert(point, to: view);
            // 让子视图再去遍历 如果有的话 进行返回操作 没有的话 不要紧 返回nil就好了
            if view.hitTest(current_point, with: event) != nil {
                return view;
            }
        }
        
        // 4 如果以上都没有找到 那就返回自己
        return self;
   
        
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值