天天看點

【iOS7的一些總結】11、iOS中的事件1、原理2、觸控事件的處理:3、 消息傳遞的響應鍊

      在應用程式成功啟動後,應用程式就開始由外部事件進行驅動。應用程式不斷擷取事件,并作出響應并更新使用者界面,然後等待下一個事件。這對事件進行循環響應的整個機制,稱為主要事件循環,由一個全局應用程式對象(一個UIApplication執行個體)進行管理。

      在事件循環中最重要的事件之一就是使用者與裝置的互動操作。在iOS裝置中,使用者對裝置的操作可以通過多種方式,如點選螢幕或者晃動裝置等。iOS作業系統會解析這些操作,并将響應通知應用做出相應。對這些操作進行更加自然和直覺的相應可以增強應用的使用者友好度。在ios中,這些響應以事件Event的方式實作。在ios中,一般把事件分為三大類:①觸控事件,用于處理使用者對螢幕的多點觸控操作;②運動事件,使用者處理裝置的移動、搖晃和方向變換等操作;③遙控事件,使用者處理使用者的遙控裝置對ios裝置的操作(如線控耳機等)。

      封裝了三種事件的UIKit類——UIEvent:UIEvent類封裝了事件的類型之外,還封裝了應用對事件的響應資訊。每一次操作發生時作業系統都會發出一個UIEvent對象,每個對象都會使用類型(type)和子類型(subtype)來表示事件的類型。

通過重寫以下方法監聽觸控事件:

在以上函數中,NSSet類型的參數touches代表觸控螢幕有幾根手指,每一個元素都是一個UITouch執行個體,可以調用tapCount方法擷取短時間内的點選次數。除此之外,還有window、view、phase等屬性,分别表示觸控發生的視窗、視圖和周期(開始、移動、結束、取消)。

UITouch類的方法主要有:

      使用者産生的事件發生之後,UIKit會産生一個包含相應的處理所需資訊的event對象,并将其放入活動app的事件隊列中。如果是觸控事件,對象封裝在UIEvent中;如果是運動事件,對象封裝根據運動類型和采用架構的不同而不同。一個事件沿事件傳遞路徑傳遞,直到找到一個可以處理目前事件的對象為止。首先,UIApplication單例對象從事件隊列的頂部取出一個事件,并通常傳送至視窗對象處理。對于觸控事件,視窗對象首先嘗試将其傳送至觸控發生的視圖對象以供處理;對于運動事件和遙控事件,視窗對象将其發送到定義的第一響應者對象處理。

(1)查找觸控事件的響應:iOS通過“觸擊檢測”(hit-testing)機制判斷發生觸控的視圖。

      衆所周知,螢幕上的視圖由父視圖和子視圖構成了一個樹形的結構,我們稱為視圖樹。觸擊檢測通過自頂向下檢測觸控發生在哪一個視圖範圍内,最終确定包含觸控發生點并且在視圖樹中最低層的視圖為目标視圖。給定視圖上的一個點(CGPoint)和事件(UIEvent),可以使用 hitTest:withEvent: 實作該功能,傳回相應的目标視圖。

(2)響應鍊由響應者對象構成:

      響應鍊由第一響應者開始,終于應用對象(UIApplication object),由響應者對象組成。在iOS中,響應者對象由UIResponder類實作,該類用于實作事件響應以及其他的響應操作,是UIApplication、UIViewController和UIView等類的基類。第一響應者是其中第一個接受事件的對象,通常為一個視圖對象。某對象稱為第一響應者,需要完成兩部:第一重寫

canBecomeFirstResponder方法并傳回YES;第二調用 becomeFirstResponder。

      響應鍊可以處理下面幾種問題:

觸控事件:如果觸擊檢測傳回的視圖不能處理該事件,事件就會沿着響應鍊向上傳遞直到某對象可以處理該事件; 運動事件:第一響應者必須實作UIResponder類的motionBegan:withEvent:和motionEnded:withEvent:方法來處理這類事件; 遙控事件:第一響應者需實作 remoteControlReceivedWithEvent:方法; Action消息:如果某個控件(如按鈕)被點選,而且該控件沒有設定target,那麼這個消息就将沿着響應鍊傳遞; 編輯菜單消息:點選編輯菜單的指令後,iOS使用響應鍊尋找可以實作編輯指令(如剪切複制粘貼等)的對象; 文本編輯:當點選文本編輯框時,該對象稱為第一響應者,同時預設彈出虛拟鍵盤。可以通過resignFirstResponder消息放棄第一響應者,可以關閉虛拟鍵盤并結束編輯狀态。隻有文本編輯框可以在使用者點選時自動稱為第一響應者,其他對象必須調用becomeFirstResponder方法來稱為第一響應者。

(3)響應鍊的響應順序:

      如果響應鍊的第一個元素(觸擊檢測傳回視圖,或者第一響應者)不能處理事件,那麼事件将會傳遞至響應鍊的第二個元素。如果響應鍊的某個元素不能處理該事件,會将其繼續向下傳遞直到響應鍊上沒有可以處理的對象為止。

      當iOS檢測到一個事件時,響應鍊開始工作,将事件傳遞給第一個元素(通常為某視圖,即初始視圖),該元素有最優先處理事件的機會。通常情況下,事件傳遞的順序為:初始視圖嘗試處理事件,如果不能處理則傳遞給其父視圖;父視圖嘗試處理事件,如果不能處理則傳遞給其父視圖,直至頂層視圖,如果頂層視圖不能處理,則傳遞給目前視圖控制器處理;如果視圖控制器不能處理,則傳遞給視窗對象處理;若視窗對象不能處理,則傳遞給應用單例對象處理;最後若應用對象不能處理,則放棄該事件。

繼續閱讀