[譯] iOS | 官方文檔 | 使用響應者和響應者鏈處理事件

前言

譯自官方文檔:Using Responders and the Responder Chain to Handle Eventsapp

概覽

App 使用響應者對象接收和處理事件。一個響應者對象能夠是UIResponder類的任何實例,常見的子類包括UIViewUIViewControllerUIApplication。響應者接收原始事件數據,而且必定會處理事件或將其發送給另外一個響應者對象。當 app 接收到事件時,UIKit會自動將該事件定向到最合適的響應者對象,即第一響應者(the first responder)。框架

未處理的事件會在一個活動的響應者鏈中,從一個響應者傳遞到另外一個響應者,這是響應者對象的動態配置(?)。 下圖顯示了一個 app 中的響應者,該程序的界面包含一個UILabel,一個UITextField,一個UIButton和兩個背景UIView。 該圖還顯示了事件如何沿着響應者鏈從一個響應者轉移到下一個響應者。測試

若是UITextField不處理事件,則UIKit會將事件發送到UITextField的父視圖,而後再接下來會發送到UIWindow的根視圖。從根視圖開始,響應程序鏈在將事件定向到UIWindow以前轉移到當前持有的UIViewController。若是UIWindow沒法處理事件,則UIKit會將事件傳遞給UIApplication對象,若是該對象是UIResponder的實例而且還不是響應者鏈的一部分,則可能傳遞給app delegate(?)。ui

肯定一個事件的第一響應者

UIKit是根據事件的類型將對象指定爲該事件的第一響應者。事件類型包括:code

事件類型 第一響應者
Touch events 發生觸摸的視圖
Press events 被 focus 的對象
Shake-motion events 你(或UIKit)指定的對象
Remote-control events 你(或UIKit)指定的對象
Editing menu messages 你(或UIKit)指定的對象

注意cdn

與加速度計,陀螺儀和磁力計有關的運動事件不遵循響應程序鏈。 相反,Core Motion 會將這些事件直接傳遞到指定的對象。 有關更多信息,請參見 Core Motion 框架。對象

控件使用action信息直接與其關聯的目標對象進行通訊。當用戶與控件交互時,控件會將action信息發送到其target對象。action消息不是事件,可是它們仍然能夠利用響應者鏈。當控件的目標對象爲nil時,UIKit從目標對象開始並遍歷響應程序鏈,直到找到實現適當操做方法的對象爲止。例如,UIKit編輯菜單使用此行爲來搜索響應者對象,這些對象實現了諸如cut(_ :)copy(_ :)paste(_ :)之類的方法。blog

手勢識別器(Gesture recognizers)會比相關視圖先接收觸摸和按下事件。若是視圖的手勢識別器沒法識別一系列觸摸,則UIKit會將觸摸發送到視圖。 若是視圖沒法處理觸摸,UIKit會將它們向上傳遞到響應者鏈。 有關使用手勢識別器處理事件的更多信息,請參見處理UIKit手勢。事件

肯定是哪一個響應者包含了觸摸事件

UIKit使用基於視圖的命中測試(hit-testing)來肯定觸摸事件發生的位置。具體來講,UIKit將觸摸位置與視圖層次結構中視圖對象的邊界(bounds of view objects)進行比較。UIViewhitTest(_:with :)方法會遍歷視圖層次結構,查找包含指定觸摸的最深子視圖,該子視圖成爲觸摸事件的第一響應者。ip

注意

若是觸摸位置在視圖範圍(a view’s bounds)以外,則hitTest(_:with :)方法將忽略該視圖及其全部子視圖。所以,若是視圖的clipsToBounds屬性爲false,即便該視圖剛好包含觸摸,也不會返回該視圖範圍以外的子視圖。有關命中測試(hit-testing)行爲的更多信息,請參見UIView中有關hitTest(_:with :)方法的討論。

發生觸摸時,UIKit將建立一個UITouch對象並將其與視圖關聯。 隨着觸摸位置或其餘參數的更改,UIKit會使用新信息更新那個UITouch對象。 惟一不變的屬性是那個關聯的視圖。 (即便觸摸位置移到原始視圖以外,觸摸的視圖屬性中的值也不會更改。)觸摸結束時,UIKit會釋放UITouch對象。

改變響應者鏈

您能夠經過覆蓋響應者對象的next(指響應鏈中下一個響應者)屬性來更改響應者鏈。

許多UIKit類已經重寫此屬性並返回特定的對象,包括:

  • UIView,若是視圖是UIViewController的根視圖,則下一個響應者是UIViewController。不然,下一個響應者是視圖的父視圖。

  • UIViewController

    • 若是UIViewController的視圖是UIWindow的根視圖,則下一個響應者是UIWindow對象。

    • 若是UIViewController是由另外一個UIViewController呈現的,則下一個響應者是第二個視圖控制器。

  • UIWindow,窗口的下一個響應者是UIApplication對象。

  • UIApplication,下一個響應者是app delegate.但僅當該app delegateUIResponder的實例且不是視圖、UIViewController或app對象自己時,纔是下一個響應者。

後記

這篇文檔講得很淺,同時也講的不怎麼容易懂,想要更深刻理解響應鏈及手勢相關內容仍是須要閱讀更多其餘優秀資料。

相關文章
相關標籤/搜索