一句話總結(jié)整個(gè)過(guò)程是:觸摸或者點(diǎn)擊一個(gè)控件览爵,然后這個(gè)事件會(huì)從上向下(從父->子)找最合適的view處理,找到這個(gè)view之后看他能不能處理嫂丙,能就處理绍傲,不能就按照事件響應(yīng)鏈向上(從子->父)傳遞給父控件
事件的傳遞和響應(yīng)的區(qū)別:
事件的傳遞是從上到下(父控件到子控件),事件的響應(yīng)是從下到上(順著響應(yīng)者鏈條向上傳遞:子控件到父控件碰声。
事件傳遞:AppDelegate -> UIApplication -> UIWindow -> UIViewController -> UIView
事件響應(yīng):UIView 找合適的子視圖诡蜓,判斷是否可以響應(yīng)事件,不可以向上傳遞胰挑,合適直接響應(yīng)事件蔓罚。
應(yīng)用啟動(dòng):
main 函數(shù)(創(chuàng)建應(yīng)用椿肩,設(shè)置應(yīng)用代理,創(chuàng)建運(yùn)行時(shí) mainRunLoop豺谈,每當(dāng)監(jiān)聽到對(duì)應(yīng)的系統(tǒng)事件時(shí)覆旱,就會(huì)通知AppDelegate,進(jìn)行事件傳遞)
應(yīng)用啟動(dòng)后核无,調(diào)用 AppDelegate 中的方法
AppDelegate:application:didFinishLaunchingWithOptions:
每個(gè)應(yīng)用都會(huì)至少有一個(gè) Window扣唱,但是只有一個(gè) KeyWindow,用來(lái)響應(yīng)事件团南,它會(huì)根據(jù)不同的 level 顯示不同的層次噪沙,不知道你是否知道 layer 上的 zindex 屬性,它可以控制繪制的位置吐根。其實(shí) Window 也是一個(gè) UIView正歼。每個(gè) window 有一個(gè) rootViewController,用來(lái)展示內(nèi)容拷橘。
首先用戶響應(yīng)事件后局义,roonLoop 接收到事件后,傳遞給 UIApplication 的事件隊(duì)列中冗疮,找到主 Window萄唇, UIViewController -> UIView。事件響應(yīng)通過(guò)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
方法決定該那個(gè)視圖響應(yīng)事件术幔,他會(huì)過(guò)濾到 隱藏的另萤,透明度小于 0.01的,和關(guān)閉交互性的視圖诅挑。
可以通過(guò) nextResponder 來(lái)改變響應(yīng)鏈四敞,大多數(shù) UIKit 已經(jīng)默認(rèn)實(shí)現(xiàn)了這個(gè)方法。
如果你重寫了 nextResponder 方法拔妥,那么下一個(gè)響應(yīng)者將是你所返回的視圖
UIView
如何視圖是 view controller 的根視圖忿危,下一個(gè)響應(yīng)者是 view controller,反之它的父視圖是下一個(gè)響應(yīng)者UIViewController
如果 view controller 的 view 是 window 的根視圖没龙,那么下一個(gè)響應(yīng)者是 window铺厨。如果一個(gè) view controller 是被另一個(gè) view controller presented 出來(lái)的,那么下一個(gè)響應(yīng)者是 presenting view controller兜畸。UIWindow.
下一個(gè)響應(yīng)者是 application努释。UIApplication
它的下一個(gè)響應(yīng)者是 AppDelegate
參考:
http://blog.flight.dev.qunar.com/2016/10/28/ios-event-mechanism-summary/