美文网首页
响应链是如何工作

响应链是如何工作

作者: switer_iOS | 来源:发表于2021-07-06 09:48 被阅读0次

    那么响应链是如何工作,正确找到应该响应该事件的响应者的?
    UIKit使用基于视图的hit-testing来确定touch事件发生的位置。具体解释就是,UIKit将touch的位置和视图层级中的view的边界进行了比较,UIView的方法 hitTest:withEvent: 在视图层级中进行,寻找包含指定touch的最深子视图。这个视图成为touch事件的第一个响应者。

    说白了就是,当有touch事件来的时候,会从最下面的视图开始执行 hitTest:withEvent: ,如果符合成为响应者的条件,就会继续遍历它的 subviews 继续执行 hitTest:withEvent: ,直到找到最合适的view成为响应者。

    这里要注意几个点:

    符合响应者的条件包括
    touch事件的位置在响应者区域内
    响应者 hidden 属性不为 YES
    响应者 透明度 不是 0
    响应者 userInteractionEnabled 不为 NO
    遍历 subview 时,是从上往下顺序遍历的,即 view.subviews 的 lastObject 到 firstObject 的顺序,找到合适的响应者view,即停止遍历.
    所以再回看上面的例子,当我们点击中间的重复区域时,流程其实是这样:

    AppDelegate 的 window 收到事件,并开始执行 hitTest:withEvent: ,发现符合要求,开始遍历子view.
    window 上只有 viewcontroller.view ,所以viewcontroller.view 开始执行 hitTest:withEvent: ,发现符合要求,开始遍历子view.
    viewcontroller.view 有两个子view, viewA 和 viewB ,但是viewB 在 viewA 上边,所以先 viewB 执行 hitTest:withEvent: ,结果发现viewB 不符合要求,因为viewB 的 userInteractionEnabled 为 NO.
    接下来 viewA 执行 hitTest:withEvent: ,发现符合条件,并且viewA 也没有子view可去遍历,于是返回viewA.
    viewA成了最终事件的响应者.
    这样就完美解释了,最开始例子的响应状况.

    那么如果 viewB 的 userInteractionEnabled 属性为YES的话,是怎么样的呢?

    如果 viewB 的 userInteractionEnabled 属性为YES,上面流程的第三部就会发现viewB是符合要求的,而直接返回viewB作为最终响应者,中断子view的遍历,viewA都不会被遍历到了.

    相关文章

      网友评论

          本文标题:响应链是如何工作

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