Swift事件传递和响应过程
2024-04-09 22:30:20  阅读数 1378

当view被点击,事件传递过程为:
1、系统检测到手指触(Touch)操作时会将其打包成一个UIEvent对象,并放入当前活动Application的事件队列
2、UIApplication将处于任务队列最前端的事件向下分发,即UIWindow
3、UIWindow将事件向下分发,即UIView
4、UIView首先看自己是否能处理事件,触摸点是否在自己身上;能处理且触摸点在自己身上,就继续寻找子视图
5、遍历子控件,重复以上两不
6、如果没有找到,即自己最适合处理事件;若自己不能处理,则不做任何处理
UIView不接受事件处理的情况:
1、alpha < 0.01
2、userInteractionEnabled = NO
3、hidden = True
4、超出父控件区域

如何确定最适合处理事件的控件?
1、自己能响应事件
2、触摸点在自己身上
3、从后往前遍历子控件,重复上两步
4、如果没有符合条件的,那么自己就是最适合处理的

当事件传递时,会调用hitTest方法返回最合适响应的view

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            //1、如果控件不允许与用户交互,那么返回nil
            if !isUserInteractionEnabled || alpha <= 0.01 || isHidden{
                print("无法交互")
                return nil
            }
            //2、如果点击的点不在当前控件中,返回nil
            if !self.point(inside: point, with: event) {
                return nil;
            }
            //3、从后往前遍历子控件
            for i in (0..<subviews.count).reversed() {
                print("i:",i)
                let childv: UIView = subviews[i]
                //当前触摸点的坐标转为相对于子控件触摸点的坐标
                let childp: CGPoint = convert(point, to: childv)
                //判断是否找到了更合适的子控件
                let fitv = childv.hitTest(childp, with: event)
                if (fitv != nil) {
                    return fitv
                }
            }
            //没找到,则返回自己
            return self
        }