iOS中的事件以下三種
1. 觸摸事件
2. 加速器事件:重力感應,旋轉等事件
3. 遠程遙控事件:藍牙線控,耳機線控等
觸摸事件
響應者對象
響應者對象是能夠響應并處理事件的對象,是構成響應鏈和事件傳遞鏈的節(jié)點。
常見的響應者對象有:UIApplication、UIViewController、UIView,都繼承自UIResponder。其繼承鏈如下:
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ā)。
從圖中可以看到,響應者鏈有以下特點:
- 響應者鏈通常是由 initial view 開始;
- UIView的nextResponder它的superview;如果UIView已經是其所在的 UIViewController的top view, 那么UIView的nextResponder 就是UIViewController;
- UIViewController 如果有 Super ViewController,那么它的 nextResponder 為其 Super ViewController 最表層的 View;如果沒有,那么它的 nextResponder 就是 UIWindow;
- UIWindow 的 contentView 指向 UIApplication,將其作為 nextResponder;
- 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