事件响应
一句话总结整个过程是:触摸或者点击一个控件,然后这个事件会从上向下(从父->子)找最合适的view处理,找到这个view之后看他能不能处理,能就处理,不能就按照事件响应链向上(从子->父)传递给父控件
事件的传递和响应的区别:
事件的传递是从上到下(父控件到子控件),事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件。
事件传递:AppDelegate -> UIApplication -> UIWindow -> UIViewController -> UIView
事件响应:UIView 找合适的子视图,判断是否可以响应事件,不可以向上传递,合适直接响应事件。
应用启动:
main 函数(创建应用,设置应用代理,创建运行时 mainRunLoop,每当监听到对应的系统事件时,就会通知AppDelegate,进行事件传递)
应用启动后,调用 AppDelegate 中的方法
AppDelegate:application:didFinishLaunchingWithOptions:
每个应用都会至少有一个 Window,但是只有一个 KeyWindow,用来响应事件,它会根据不同的 level 显示不同的层次,不知道你是否知道 layer 上的 zindex 属性,它可以控制绘制的位置。其实 Window 也是一个 UIView。每个 window 有一个 rootViewController,用来展示内容。
首先用户响应事件后,roonLoop 接收到事件后,传递给 UIApplication 的事件队列中,找到主 Window, UIViewController -> UIView。事件响应通过
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
方法决定该那个视图响应事件,他会过滤到 隐藏的,透明度小于 0.01的,和关闭交互性的视图。
可以通过 nextResponder 来改变响应链,大多数 UIKit 已经默认实现了这个方法。
如果你重写了 nextResponder 方法,那么下一个响应者将是你所返回的视图
-
UIView
如何视图是 view controller 的根视图,下一个响应者是 view controller,反之它的父视图是下一个响应者 -
UIViewController
如果 view controller 的 view 是 window 的根视图,那么下一个响应者是 window。如果一个 view controller 是被另一个 view controller presented 出来的,那么下一个响应者是 presenting view controller。 -
UIWindow.
下一个响应者是 application。 -
UIApplication
它的下一个响应者是 AppDelegate
参考:
http://blog.flight.dev.qunar.com/2016/10/28/ios-event-mechanism-summary/