第一反应就是,响应链就是响应链啊,由一串UIResponder对象链接,收到响应事件时由上往下传递,直到能响应事件为止。
这里要注意几个点:
- 符合响应者的条件包括
- 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都不会被遍历到了.
这就是响应链相关的点,如果有什么不对的请留言提示,然后有什么别的需要补充的我会及时补充~



