ios 事件传递和响应链
2021-07-18 本文已影响0人
qui丶MyLove
事件传递
当一个事件触发,系统会将事件放入UIApplication事件处理队列中,UIApplication从队列中取出事件发送给UIWindow,UIWindow通过hitTest去寻找最合适的view处理事件。
hitTest调用时机是在事件传给它就会调用hitTest,并且通过pointInside判断点是否在它上面,如果在它上面就会将它的所有子控件都调用hitTest和pointInside继续查找。如果子控件没有找到那么它的父控件就是最适合的。
如果父控件不能接受触摸事件,那么子控件就不可能接收到触摸事件。
响应链
找到最适合的view,当view不能处理事件时会将事件传给它的下一个响应者处理,一直找不到能处理的对象,最终会传回UIApplication,如果UIApplication也不能处理那么此事件将被丢弃。
view 是否能处理事件,即看view是否重写了touches的方法。当view没有重写touches方法处理事件,则会直接super 调用touches方法传到下一个响应者。
代码测试 hittest执行顺序
图1点击c绿色中心位置事件传递链 window -->a__hittest&pointinside___->b___hittest&pointinside____->c
注释:点击c事件会从UIApplication 传给window,window会执行hittest然后通过pointinside判断是在点击在window内,从而调用window上的子控件的hittest和pointinside,找到a将事件传递给a,a重复window的操作找到了c是最终的view,事件传递到了c。
注:扩大按钮响应方法可以重写pointInside
事件响应处理
重写按钮c的touches方法cAction不能响应事件被截获注释:事件传递到最合适的view之后开始判断是否能响应处理事件,重写了c的touches方法c按钮本身设置的action就无法响应。响应链即是从view通过touches方法去响应,本身没有重写touches方法处理事件则通过super调用touches传递给父控件。这个传递过程就形成了响应链。
注:多对象处理事件就可以这么实现