美文网首页
响应者链条!!!看我的

响应者链条!!!看我的

作者: 我是繁星 | 来源:发表于2018-04-07 22:45 被阅读0次

    比较官方的解释:

    用户事件发生的时候,UIKit会创建一个事件对象Event Object,该对象包含事件处理所必须的一些信息。然后会将事件对象置于激活的app事件队列。例如触摸事件就是对象一系列触摸信息的包装集。
    包含两个过程

    说说理解:

    整个过程分为两部分(查找相应者)和(响应者处理),并且是由responder连接起来的,也就是响应链名字的由来
    查找响应者:从UIWindow开始,顺着视图树查找到目标响应者。
    响应者处理:touches方法由原路下发。
    手势也是通过响应链处理的,但是手势可以阻断父视图touches方法。的传播。

    Demo:

    image.png

    首先创建redView、blueView继承自UIView,一白一红,分别在hitTest、pointInside和touchesBegan中添加打印。
    1.redView加到self.view上,blueView加到redView上。
    2.redView和blueView都加到self.view上覆盖。
    3.redView加到self.view上,blueView加到redView上,redView isUserInteractionEnabled = false。
    4.redView和blueView都加到self.view上覆盖,redView isUserInteractionEnabled = false。
    依次打印结果如下:


    image.png image.png image.png image.png image.png

    对比1、4 redView的isUserInteractionEnabled = false ,所以对应view的hitTest返回nil。其所有子视图都无法接收事件了(所以加到UIImageView上的视图默认是都接收不到事件的)。

    对比2、4 redView的isUserInteractionEnabled = false,blueView还可以接收事件,因为是redView和blueView无父子视图的关系,所以同级时redView不接收事件与blueView无关。

    对比1、2 当redView和blueView同时加到self.view上的时候时,且有重合区域,后加到self.view上的在上面(默认,可调换),优先接收事件。

    总结:

    当有触摸行为发生后会从UIWindow开始调用hitTest-> pointInside判断是否在范围内,如果在的话依次调用其子视图的hitTest-> pointInside判断是否在其子视图范围内,如果子视图有重叠则显示在上面的响应,找到目标View(响应手势的View),touchesBegin等方法会回调,且依次执行父视图的touchesBegin等方法(注意这里父视图的手势并不能响应)。

    Demo:https://github.com/starFanX/-Demo

    最后再说说手势和UIButton

    不知道大家有没有发现UIButton的父视图是无法响应touches方法的,原因当然是UIButton阻断了响应链,如果想继续传递的话可以重写button,直接调用他的nextRespond的touches方法、3个都要写。

      override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            self.next?.touchesBegan(touches, with: event)
        }
    

    关于UIGestureRecognizer,大家用的时候回发现,如果不做特殊处理的话,多个重叠的view都添加了手势,只会响应命中view添加的手势,且手势并不会阻断响应者链条,其实我们可以通过一系列UIGestureRecognizerDelegate去控制手势的响应
    例如:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool 
    //标识相同类型的手势都会得到响应。
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
    //判断收到的手势是否响应。可以通过
    

    相关文章

      网友评论

          本文标题:响应者链条!!!看我的

          本文链接:https://www.haomeiwen.com/subject/dovyhftx.html