JHHK

欢迎来到我的个人网站
行者常至 为者常成

事件传递和响应者链

目录

事件传递

1、事件传递

1、iOS 检测到手指触摸,打包成一个UIEvent对象
2、springBoard
3、通过端口传递给当前进程
4、触发sorce1回调
5、soruce0回调
6、放入当前活动Application的事件队列
7、UIApplication 会从事件队列中取出触摸事件并传递给单例的 UIWindow 来处理
8、UIWindow 对象首先会使用 hitTest:withEvent:方法
9、方法内部调用pointInside来判断触点是否在自身上

    如果在返回YES     
        如果有子view调用子view的hitTest,不断向下递归,寻找响应者    
        如果没有子view,返回自身,自身就是响应者    
    如果不在返回NO     
        返回nil,响应者不是自身或子view      

响应者链

一、找到响应者之后事件是如何响应的

view(First Responser) –> 父View–>VC->The Window –> The Application –> nil(丢弃)

响应者链过程

1、调用响应者的touchBegain方法,此方法的默认实现将消息向上转发到响应程序链。
如果在不调用super(一种常用模式)的情况下重写此方法,则必须重写用于处理触摸事件的其他方法,即使您的实现什么也不做。

2、如果重写了touchBegain来处理事件,响应链会中断。
要想继续响应者链,可调用了 父类 的touchBegain,事件会被传递到父view.
注意父类和父view的区别。

3、如果响应者添加了手势,手势回调处理完成后,会调用响应者的touchesCancelled。

二、无法响应的情况

1.Alpha=0、hidden=YES、子视图超出父视图的情况、userInteractionEnabled=NO 视图会被忽略,不会调用hitTest
2.父视图被忽略后其所有子视图也会被忽略,所以View3上的button不会有点击反应
3.出现视图无法响应的情况,可以考虑上诉情况来排查问题

三、应用示例

限定点击区域
给定一个显示为圆形的视图,实现只有在点击区域在圆形里面才视为有效。
我们可以重写View的pointInside方法来判断点击的点是否在圆内,也就是判断点击的点到圆心的距离是否小于等于半径就可以。


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.