很多類型事件的傳遞都依賴于響應者鏈烧董。響應者鏈是一系列響應者對象的關(guān)系集。它始于第一響應者而終于Application對象舀锨。如果第一響應者不能處理這個事件骂际,它會將事件傳遞給響應者鏈中得下一個響應者。
第一響應者是一個可以響應并處理事件的對象业栅。UIResponder就是所以響應者對象的基類秒咐,它定義了一些通用的接口并不僅僅只是事件的處理還有普遍的響應者行為。UIApplication碘裕,UIcontroller携取,和UIview類的實例都是響應者,這就意味所有的view和大多數(shù)關(guān)鍵的controller對象都是響應者帮孔。值得注意的是核心動畫圖層Core?Animation layers不是響應者雷滋。(看看它們都是繼承誰就就知道啦)
第一響應者被設計為優(yōu)先獲得處理事件的能力。比較典型的是文兢,第一響應者是view對象晤斩,一個響應者對象要成為第一響應者必須經(jīng)過下面兩件事:
1. 覆蓋canBecomeFirstResponder方法并且返回YES
2. 收到becomeFisrtResponder消息。如果有必要的話姆坚,響應者對象可以給自己發(fā)送這樣的消息澳泵。
注意:指定第一響應者對象之前一定要確認你的app已經(jīng)被建立。例如兼呵,你比較典型的調(diào)用becomeFirstRespnder方法在viewDidAppear:方法中兔辅。如果你嘗試著在viewWillAppear:去指定第一響應者,你的對象繪制還沒有被建立击喂,以至于becomeFirstResponder方法會返回NO维苔。
事件并不是唯一依賴響應者鏈的對象。響應者鏈通常被使用宇一下所有的情況:
觸摸事件:如果命中測試view不能處理觸摸事件懂昂,這個事件就會被傳遞到響應者鏈中命中view的上一個響應者介时。
手勢事件:使用UIKit去處理震動手勢事件,第一響應者必須要么實現(xiàn)UIResponderd的motionBegain:withEvent:方法要么實現(xiàn)motionEnded:withEvent:方法
遠程控制事件:為了去處理“遠程控制事件”,第一響應者必須實現(xiàn)UIResponder的remoteControlReceivedWithEvent:方法沸柔。
行為消息:當用戶操作一個控制循衰,例如一個button或者switch,并且行為方法的目標是nil勉失,這個消息將會被通過響應者鏈從控制器view開始發(fā)送。
如果initial object(初始對象)命中測試view或者第一響應者不能處理該事件原探,UIKit會遞交事件給響應者鏈中的下一個響應者乱凿。每一個響應者都有權(quán)決定它是否想要去處理該事件或者是繼續(xù)遞交給它自己的下一個響應者通過調(diào)用nextResponder方法。這個過程將會持續(xù)到某個響應者處理該事件或者沒有更多的響應者為止咽弦。
響應者鏈隊列始于iOS偵測事件并且遞交她給initial對象徒蟆,那是一個典型的view。這個initialview具備優(yōu)先處理事件的權(quán)利型型,如圖:2-2顯示了兩個不同的應用構(gòu)造的兩個不同的事件傳遞路徑段审。一個app的事件傳遞路徑取決于它自身的構(gòu)造,但是所有的事件傳遞都遵循相同的傳遞規(guī)則闹蒜。
圖:2-2 ? iOS響應者鏈
對于左邊的app寺枉,事件傳遞按下面的路徑:
1. ?Initial view 嘗試著去處理事件或者消息。如果不能處理事件绷落,它就遞交事件給superview,因為這個initial view并不是視圖控制器層級中得頂級view.
2. ?這個superview嘗試去處理該事件姥闪,如果superview不能處理該事件,它就遞交事件給它的父view砌烁,因為它也不是view層級的頂級view筐喳。
3. ?視圖控制器的頂級view嘗試著去處理該事件,如果連頂級view都不能處理該事件函喉,它就遞交事件給它的controller避归。
4. ?這個viewcontroller嘗試著去處理該事件,并且如果它不能處理該事件管呵,它就會遞交事件給window梳毙。
5. ?如果window不能處理該事件,它就遞交事件給singlegon app object(既UIApplication)
6. ?如果連application都不能處理該事件捐下,那么毫無疑問該事件將會被丟棄顿天。
右邊的應用傳遞按照稍微不同的路徑,但是所有的事件傳遞都遵循相同的傳遞規(guī)則:
1. ?一個view controller層級中得view向上遞交事件知道它到達頂級view蔑担。
2. ?頂級view遞交事件給它的controller牌废。
3. ?Viewcontroller遞交事件給它的頂級view的superview,步驟1-3重復直到它到達rootcontroller啤握。
4. ?這個rootviewcontroller遞交事件給window對象鸟缕。
5. ?window對象遞交事件給application對象。