iOS 事件處理機(jī)制

在iOS中,事件被封裝成 UIEvent對(duì)象,主要有以下屬性

@property(nonatomic,readonly) UIEventType type; //事件類型
@property(nonatomic,readonly)UIEventSubtype subtype;
@property(nonatomic,readonly)NSTimeInterval timestamp;//事件產(chǎn)生時(shí)間

事件分為以下三類

1,觸摸事件 UIEventTypeTouches

2,運(yùn)動(dòng)事件 UIEventTypeMotion

3,遠(yuǎn)程控制事件 UIEventTypeRemoteControl

在iOS中并不是所有的類都能處理接收并事件,只有繼承自UIResponder類的對(duì)象(響應(yīng)者對(duì)象)才能處理事件,我們常用的UIView、UIViewController、UIApplication都繼承自UIResponder,它們都能接收并處理事件。

UIResponder 提供以下方法來處理事件

  • 觸摸事件
//一根或多根手指開始觸摸view,系統(tǒng)會(huì)自動(dòng)調(diào)用view下面的方法:
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
// 一根或者多根手指在view上移動(dòng)時(shí),系統(tǒng)會(huì)持續(xù)的自動(dòng)調(diào)用view下面的方法:
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
//一根或者多根手指離開view,系統(tǒng)會(huì)自動(dòng)調(diào)用view下面的方法:
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
//觸摸結(jié)束前,某個(gè)系統(tǒng)事件(例如電話呼入)會(huì)打斷觸摸過程,系統(tǒng)會(huì)自動(dòng)調(diào)用view下面的方法
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event

當(dāng)用戶用一根手指觸摸屏幕時(shí),會(huì)創(chuàng)建一個(gè)與手指相關(guān)聯(lián)的 UITouch 對(duì)象,主要有以下屬性:

@property(nonatomic,readonly,retain)UIWindow *window; //觸摸產(chǎn)生時(shí)所處的窗口
@property(nonatomic,readonly,retain)UIView *view;//觸摸產(chǎn)生時(shí)所處的視圖
@property(nonatomic,readonly) NSUInteger tapCount;//點(diǎn)擊次數(shù)
@property(nonatomic,readonly)NSTimeInterval timestamp;//觸摸產(chǎn)生時(shí)間
@property(nonatomic,readonly)UITouchPhase phase;//觸摸所處狀態(tài)

UITouch與UIEvent
  • 運(yùn)動(dòng)事件
 //運(yùn)動(dòng)開始
 -(void)motionBegan:(UIEventSubtype)motionwithEvent:(UIEvent*)event
//運(yùn)動(dòng)結(jié)束
-(void)motionEnded:(UIEventSubtype)motionwithEvent:(UIEvent*)event
//運(yùn)動(dòng)被取消
-(void)motionCancelled:(UIEventSubtype)motionwithEvent:(UIEvent*)event
  • 遠(yuǎn)程控制事件事件
//接收到遠(yuǎn)程控制消息
-(void)remoteControlReceivedWithEvent:(UIEvent*)event
觸摸事件處理機(jī)制

對(duì)于UIView,有三種情況不接受觸摸事件

  • userInteractionEnable = NO;
  • hidden = YES;;
  • alpha = 0.0~0.01;

當(dāng)發(fā)生觸摸時(shí),系統(tǒng)會(huì)封裝一個(gè)事件,事件會(huì)加入到UIApplication事件隊(duì)列,通常分發(fā)給應(yīng)用程序主窗口(window)



主窗口會(huì)通過以下方法從視圖結(jié)構(gòu)尋找合適的視圖

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

例如用戶點(diǎn)擊了 View E


尋找過程為

從 View A 的 Subview View B 與 View C 中尋找,
發(fā)現(xiàn)在View C 內(nèi),再?gòu)腣iew D 與 View E中尋找
在View E內(nèi)

因此,事件的傳遞過程為:UIApplication->Window->View A->View C->view E

事件的響應(yīng)鏈 The Responder Chain
iOS_responder_chain

如果初始化對(duì)象(initial object)—— 即initial view 不處理事件(處理事件通過touches..方法響應(yīng)),UIKit會(huì)將事件傳遞給responder chain的下一個(gè)responder。每個(gè)responder決定它是傳遞事件還是通過nextResponder方法傳遞給它的下一個(gè)responder。這個(gè)操作繼續(xù)直到UIApplication,然后廢棄。

參考文檔

About Events in iOS

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

推薦閱讀更多精彩內(nèi)容