事件傳遞和響應(yīng)機制

iOS中的事件

1.事件的生命周期

事件的生命周期從事件的產(chǎn)生和傳遞(事件如何從父控件傳遞到子控件并尋找到最合適的view氛堕、尋找最合適的view的底層實現(xiàn)泪蔫、攔截事件的處理)->事件的響應(yīng)(找到最合適的view后對事件進行處理,touches方法的重寫)

2.事件的分類

iOS中的事件可以分為3大類型:

  • 觸屏事件(例如點擊按鈕进每、通過手勢縮放圖片捐名、拖動上下滾動頁面等)
  • 傳感器事件(例如搖一搖紅包辨萍、通過旋轉(zhuǎn)設(shè)備控制賽車方向烘跺、指南針等)
  • 遠程控制事件(例如耳機的線控湘纵、外接手柄、遙控器等)

3.響應(yīng)者對象(UIResponder)

在iOS中只有繼承了UIResponder的對象才能接收和處理事件滤淳,UIResponder的子類包括UIView梧喷,UIViewController,UIApplication等。響應(yīng)者接收到原始事件數(shù)據(jù)铺敌,必須處理事件轉(zhuǎn)發(fā)到另一個響應(yīng)者對象绊困,當(dāng)APP接收到一個事件事,UIKit自動引導(dǎo)事件到最合適的的響應(yīng)者對象适刀,也叫做第一響應(yīng)者。
UIResponder內(nèi)部提供了以下方法來處理事件

觸摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
加速計事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
遠程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

4.事件中的概念

在自定義UIView為屬性的控件時可以重寫觸摸事件的方法來進行點擊回調(diào)煤蹭。在回調(diào)中可以看到方法接收兩個參數(shù)笔喉,一個是UITouch對象的集合,還有一個是UIEvent對象硝皂。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"觸摸開始--touches:%@,event:%@",touches,event);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"開始移動--touches:%@,event:%@",touches,event);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"觸摸結(jié)束--touches:%@,event:%@",touches,event);
}
//只有在程序強制退出或者來電時才會調(diào)用
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"觸摸取消--touches:%@,event:%@",touches,event);
}

4.1UIEvent

表示用戶交互的事件對象常挚,每產(chǎn)生一個事件,就會產(chǎn)生一個UIEvent對象稽物。在一個用戶點擊事件處理過程中奄毡,UIEvent對象是唯一的。
UIEvent屬性如下:

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

4.2UITouch

當(dāng)用戶用一根手指觸摸屏幕時贝或,會創(chuàng)建一個與手指相關(guān)的UITouch對象 吼过,一根手指對應(yīng)一個UITouch對象。
UITouch屬性如下:

//觸摸產(chǎn)生時所處的窗口
@property(nonatomic,readonly,retain) UIWindow *window;
//觸摸產(chǎn)生時所處的視圖
@property(nonatomic,readonly,retain) UIView *view
;
//短時間內(nèi)點按屏幕的次數(shù)咪奖,可以根據(jù)tapCount判斷單擊盗忱、雙擊或更多的點擊
@property(nonatomic,readonly) NSUInteger tapCount;
//記錄了觸摸事件產(chǎn)生或變化時的時間,單位是秒
@property(nonatomic,readonly) NSTimeInterval timestamp;
//當(dāng)前觸摸事件所處的狀態(tài)
@property(nonatomic,readonly) UITouchPhase phase;

UITouch方法如下:

// 返回值表示觸摸在view上的位置
// 這里返回的位置是針對view的坐標系的(以view的左上角為原點(0, 0))
// 調(diào)用時傳入的view參數(shù)為nil的話羊赵,返回的是觸摸點在UIWindow的位置
(CGPoint)locationInView:(UIView *)view;
// 該方法記錄了前一個觸摸點的位置
(CGPoint)previousLocationInView:(UIView *)view;

事件的傳遞和響應(yīng)

1.事件的產(chǎn)生和傳遞

1.1事件的產(chǎn)生

1.發(fā)生觸摸事件后趟佃,系統(tǒng)會將該事件加入到一個由UIApplication管理的隊列事件中
2.UIApplication會從事件隊列中取出最前面的事件,并將事件分發(fā)下去以便處理昧捷,通常會先發(fā)送事件給應(yīng)用程序的主窗口(keyWindow)
3.主窗口會在視圖層次結(jié)構(gòu)中找到一個最合適的視圖來處理觸摸事件

1.2事件的傳遞

觸摸事件的傳遞是從父控件傳遞到子控件闲昭。事件傳遞給窗口或者控件后,就調(diào)用hitTest:withEvent:方法尋找更合適的view靡挥。方法底層會調(diào)用pointInside:withEvent:方法判斷點在不在方法調(diào)用者的坐標系上序矩,如果返回YES說明點在當(dāng)前view上,繼續(xù)通過hitTest:withEvent:方法遍歷子控件芹血,直到找到最合適的view贮泞。如返回NO,代表事件不在view內(nèi)幔烛,直接返回nil啃擦,說明當(dāng)前view不是最合適的view,其以下的子控件也都會被忽略饿悬。
這個方法會忽略以下情況:

  • 視圖是隱藏的 hidden = YES
  • 用戶交互是關(guān)閉的 userInteractionEnabled = NO
  • 透明度小于0.01的 alpha < 0.01

2.事件的響應(yīng)

  • 響應(yīng)者鏈條
    在ios程序中每個控件的擺放是有前后關(guān)系的令蛉,這種先后關(guān)系構(gòu)成的一個鏈條就叫響應(yīng)者鏈。
  • 響應(yīng)者鏈的事件傳遞過程
    1.如果當(dāng)前view是控制器的view,那么控制器就是上一個響應(yīng)者珠叔,事件就傳遞給控制器蝎宇;如果當(dāng)前view不是控制器的view,那么父視圖就是當(dāng)前view的上一個響應(yīng)者祷安,事件就傳遞給它的父視圖
    2.在視圖層次結(jié)構(gòu)的最頂級視圖姥芥,如果也不能處理收到的事件或消息,則其將事件或消息傳遞給window對象進行處理
    3.如果window對象也不處理汇鞭,則其將事件或消息傳遞給UIApplication對象
    4.如果UIApplication也不能處理該事件或消息凉唐,則將其丟棄
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市霍骄,隨后出現(xiàn)的幾起案子台囱,更是在濱河造成了極大的恐慌,老刑警劉巖读整,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件簿训,死亡現(xiàn)場離奇詭異,居然都是意外死亡米间,警方通過查閱死者的電腦和手機强品,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來车伞,“玉大人择懂,你說我怎么就攤上這事×砭粒” “怎么了困曙?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谦去。 經(jīng)常有香客問我慷丽,道長,這世上最難降的妖魔是什么鳄哭? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任要糊,我火速辦了婚禮,結(jié)果婚禮上妆丘,老公的妹妹穿的比我還像新娘锄俄。我一直安慰自己,他們只是感情好勺拣,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布奶赠。 她就那樣靜靜地躺著,像睡著了一般药有。 火紅的嫁衣襯著肌膚如雪毅戈。 梳的紋絲不亂的頭發(fā)上苹丸,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音苇经,去河邊找鬼赘理。 笑死,一個胖子當(dāng)著我的面吹牛扇单,可吹牛的內(nèi)容都是我干的商模。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蜘澜,長吁一口氣:“原來是場噩夢啊……” “哼阻桅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兼都,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稽寒,沒想到半個月后扮碧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡杏糙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年慎王,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宏侍。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡赖淤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谅河,到底是詐尸還是另有隱情咱旱,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布绷耍,位于F島的核電站吐限,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褂始。R本人自食惡果不足惜诸典,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崎苗。 院中可真熱鬧狐粱,春花似錦、人聲如沸胆数。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幅慌。三九已至宋欺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背齿诞。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工酸休, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人祷杈。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓斑司,卻偏偏與公主長得像,于是被迫代替她去往敵國和親但汞。 傳聞我的和親對象是個殘疾皇子宿刮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

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