iOS事件處理

iOS中的事件以下三種
1. 觸摸事件
2. 加速器事件:重力感應,旋轉等事件
3. 遠程遙控事件:藍牙線控,耳機線控等

觸摸事件

響應者對象

響應者對象是能夠響應并處理事件的對象,是構成響應鏈和事件傳遞鏈的節(jié)點。
常見的響應者對象有:UIApplication、UIViewController、UIView,都繼承自UIResponder。其繼承鏈如下:


responder 繼承鏈

UIResponder的類相關定義如下:

@interface UIResponder : NSObject

- (nullable UIResponder*)nextResponder;

- (BOOL)canBecomeFirstResponder;    // default is NO
- (BOOL)becomeFirstResponder;

- (BOOL)canResignFirstResponder;    // default is YES
- (BOOL)resignFirstResponder;

- (BOOL)isFirstResponder;

/**** 觸摸事件方法,對觸摸事件進行處理 *****/
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEstimatedPropertiesUpdated:(NSSet * _Nonnull)touches NS_AVAILABLE_IOS(9_1);

/*** 加速器事件方法,對其進行處理  ***/
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);

/***  遙控事件方法 ***/
- (void)remoteControlReceivedWithEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(4_0);

@end

從UIResponder類中可以看到,需要處理觸摸,加速器和遙控等事件時需要重寫響應的方法,對UITouch和UIEvent進行處理。

UITouch對象是一個手指接觸到屏幕并在屏幕上移動或離開屏幕時創(chuàng)建的。它有幾個屬性和實例方法:

phase:屬性,返回一個階段常量,指出觸摸開始、繼續(xù)、結束或被取消,是一個枚舉配型,包含了
·UITouchPhaseBegan(觸摸開始)
·UITouchPhaseMoved(接觸點移動)
·UITouchPhaseStationary(接觸點無移動)
·UITouchPhaseEnded(觸摸結束)
·UITouchPhaseCancelled(觸摸取消)
tapCount:屬性,輕按屏幕的次數(shù)
timeStamp:屬性,觸摸發(fā)生的時間
view:屬性,觸摸始于那個視圖
window:屬性,觸摸始于哪個窗口
lacationInView:方法,觸摸在指定視圖中的當前位置
previousLocationView:方法,觸摸在指定視圖中的前一個位置

UIEvent對象包含一組相關的UITouch對象,由UITouch對象組成UIEvent對象,可以理解成一個完整的觸摸操作是一個UIEvent,而這一系列完整操作中的每個點就是UITouch(按下、移動、離開)。
UIEvent的作用是提供相關觸摸操作的列表,如果要獲取在屏幕上觸摸的手勢,可以使用該對象,這一些列操作都存儲在Foundation框架中的NSSet對象中。

響應鏈

當觸摸事件發(fā)生時,必須知道有誰來響應事件,所以會進行一個事件響應的一個傳導,這就叫做響應鏈。

每一個應用有一個響應者鏈,我們的視圖結構是一個N叉樹(一個視圖可以有多個子視圖,一個子視圖同一時刻只有一個父視圖),而每一個繼承UIResponder的對象都可以在這個N叉樹中扮演一個節(jié)點。當葉節(jié)點成為最高響應者的時候,從這個葉節(jié)點開始往其父節(jié)點開始追朔出一條鏈,那么對于這一個葉節(jié)點來講,這一條鏈就是當前的響應者鏈。響應者鏈將系統(tǒng)捕獲到的UIEvent與UITouch從葉節(jié)點開始層層向下分發(fā),期間可以選擇停止分發(fā),也可以選擇繼續(xù)向下分發(fā)。

事件響應鏈

從圖中可以看到,響應者鏈有以下特點:

  1. 響應者鏈通常是由 initial view 開始;
  1. UIView的nextResponder它的superview;如果UIView已經是其所在的 UIViewController的top view, 那么UIView的nextResponder 就是UIViewController;
  2. UIViewController 如果有 Super ViewController,那么它的 nextResponder 為其 Super ViewController 最表層的 View;如果沒有,那么它的 nextResponder 就是 UIWindow;
  3. UIWindow 的 contentView 指向 UIApplication,將其作為 nextResponder;
  4. UIApplication 是一個響應者鏈的終點,它的 nextResponder 指向nil,整個 responder chain 結束。

所有事件響應的類都是UIResponder的子類,響應者鏈是一個由不同對象組成的層次結構,其中的每個對象將依次獲得響應事件消息的機會。當發(fā)生事件時,事件首先被發(fā)送給第一響應者,第一響應者往往是事件發(fā)生的視圖,也就是用戶觸摸屏幕的地方。事件將沿著響應者鏈一直向下傳遞,直到被接受并做出處理。

一個典型的響應鏈路線圖如下:

initial view –> super view –> …..–> view controller –> window –> Application –> AppDelegate

hitTest

當用戶與 iPhone 的觸摸屏產生互動時,硬件就會探測到物理接觸并且通知操作系統(tǒng)。操作系統(tǒng)就會創(chuàng)建相應的事件,并將其傳遞給當前正在運行的應用程序的事件隊列。然后這個事件會被事件循環(huán)傳遞給優(yōu)先響應對象,即 Hit-Test View 。

Hit-Test View 就是事件被觸發(fā)時和用戶交互的對象,尋找 Hit-Test View 的過程就叫做 Hit-Testing。

參考文章:
深入淺出iOS事件機制
Responder一點也不神秘——iOS用戶響應者鏈完全剖析
iOS Events and Responder Chain

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 好奇觸摸事件是如何從屏幕轉移到APP內的?困惑于Cell怎么突然不能點擊了?糾結于如何實現(xiàn)這個奇葩響應需求?亦或是...
    Lotheve閱讀 57,990評論 51 603
  • 在iOS開發(fā)中經常會涉及到觸摸事件。本想自己總結一下,但是遇到了這篇文章,感覺總結的已經很到位,特此轉載。作者:L...
    WQ_UESTC閱讀 6,121評論 4 26
  • iOS事件分類以及相關方法 在iOS中事件分為三類: 觸摸事件:通過觸摸、手勢進行觸發(fā)(例如手指點擊、縮放、旋轉)...
    木_木27閱讀 1,699評論 0 6
  • 1. iOS中的事件可以分為3大類型:觸摸事件、加速事件、遠程控制事件 2.按照時間順序,事件的生命周期是這樣的:...
    彬至睢陽閱讀 363評論 0 0
  • 事件 移動應用中常用的事件 處理事件的條件: 在iOS中,不是任何對象都能處理事件,只有繼承了UIResponde...
    叫我Dragon閱讀 1,826評論 0 1