UIResponder簡要

關於UIResponder,我這邊就簡要的說一下響應鏈,firstResponder

1.響應鏈:

在UIResponder中有一個非常重要的概念叫做Responder Chain,個人的理解是這是按照一定規則組織的響應、處理事件的一條鏈表。在瞭解UIResponder之前還得在瞭解一個概念Hit-Testing。在IOS中通常使用hit-testing去找到那個被觸摸的視圖。這個視圖叫hit-test view,當IOS找到hit-test view後就把touch event交個那個視圖來處理。下面畫個圖來說明一下,當點擊視圖E時看一下hit-testing的工作過程。

1.確定改觸摸事件發生在view A範圍內,接下來測試view B以及view C。

2.檢查發現事件不再view B範圍內發生,接下來檢查view C發現觸摸事件發生在了view C中,所以檢查 view D,view E。

3.最後發現事件發生在view E的範圍內所以view E成爲了hit-test view。

摘自:http://blog.csdn.net/jimzhai/article/details/23283515

Responder Chain 是由responder對象組成的

responder chain是由一系列responder對象連接起來的,他從第一個responder對象開始一直到application對象結束。如果第一個responder不能夠處理該事件則該事件會被髮送到下一個在該responder chain中的responder來處理。
當自己定義的一個類想讓他成爲first responder時需要做兩件事:
1.重寫 canBecomeFirstResponder 方法讓他返回YES
2.接受 becomeFirstResponder 消息,如果必要的話可讓對象給自己發送該消息。
 
在這裏有一個地方需要注意,當把一個對象變爲first responder是要確保這個對象的圖形界面已經建立起來,也就是說要在viewDidAppear中調用becomeFirstResponder方法。如果在veiwWillAppear方法中調用becomeFirstResponder將會得到一個NO。
 

Responder Chain 遵循一個特定的傳播路徑

如果hit-test view不能夠處理該事件則UIKit會將事件傳遞給下一個Responder。下圖則顯示了事件在Responder Chain中傳播的兩種方式:
對於左邊的app中事件傳播路徑如下:
1.初始的界面嘗試去處理事件後者消息,打他處理不了則把事件交給它上一層視圖處理,因爲最開始的界面在他的view controller裏的視圖層次裏不是最上層的。(這裏的上下是按照樹的結構而言的,下圖解釋:)
Art/view_hierarchy_relationships.jpg
 
2.上層視圖嘗試處理事件,如果他不能處理則將事件交給他的上層視圖處理,原因同上。
3.在view controller中最上層的視圖嘗試處理,他也不能處理則交給他的view controller來處理。
4.view controller也無法處理則交給window來處理。
5.window無法處理交給app object來處理
6.app object無法處理則將該事件丟棄掉。
右邊的傳播方式稍有不同:
1.一個視圖在他的view controller 的視圖層中向上傳播一個事件直到它到達最頂層視圖。
2.最頂層視圖無法處理將event交給他的view controller來處理。
3.view controller 傳遞事件到他的最頂層視圖的上一層視圖,接下來重複1-3的步驟直到事件到達root view controller。
4.root view controller將事件傳遞到window object。
5.window 將事件傳遞給app object。
 
注意:事件,消息不要自己向上傳送而要調用父類中的方法來處理,讓UIKit來處理消息在responder chain中的傳遞。
 
2.關於firstResponder 
 作爲FirstResponder,整個界面中有且只有一個能成爲FirstResponder
 2.1 在textfield中我們知道只要將textField becomeFirstResponder 那麼就會彈起鍵盤,那麼如果是別的呢?
 2.2 後來實驗發現,
       首先要能成爲firstResponder 就要實現這個方法
  
- (BOOL)canBecomeFirstResponder {
    return YES;
}

   然後需要新建一個屬性

@property (nonatomic,strong) UIView *inputView;

       記住,你沒看錯,就是叫inputView,跟textField一樣,你不能叫別的名字,然後將inputView實例化,就能彈出來了,

  說實話,我剛看到別人這麼寫的時候,總感覺不可能,然後就沒去實驗,不過貌似事實就是這樣,只要我們給inputView一個值,那麼就會像鍵盤一樣彈起的。

3. UIResponder

我們可以重寫或者Category來添加UIResponder事件,但是如果這個事件要具備響應鏈的特性的話,需要實現方法

- (void)func {

  [self.nextResponder func];

}

並且在子類重寫func時,如果需要響應鏈,那麼必須super方法。。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章