響應(yīng)者鏈

If I have seen further(than.Descartes)it is by standing upon the shoulders of Giants.

巨人1? ?巨人2??巨人3




一族淮、事件分類

iOS系統(tǒng)操作設(shè)備的方式主要有三種:觸摸屏幕规肴、晃動(dòng)設(shè)備驾孔、通過(guò)遙控設(shè)施控制設(shè)備依痊。對(duì)應(yīng)的事件類型有以三種:1、觸屏事件(Touch Event)2、運(yùn)動(dòng)事件(Motion Event)3咪惠、遠(yuǎn)端控制事件(Remote-Control Event)


事件分類1


事件分類2
處理事件的方法

以觸屏事件(Touch Event)為例,來(lái)說(shuō)明在Cocoa Touch框架中淋淀,事件的處理流程遥昧。


二覆醇、響應(yīng)者鏈(Responder Chain)

UIResponder?。響應(yīng)者對(duì)象是指有響應(yīng)和處理事件能力的對(duì)象炭臭。響應(yīng)者鏈就是由一系列的響應(yīng)者對(duì)象構(gòu)成的一個(gè)層次結(jié)構(gòu)永脓。

UIResponder是所有響應(yīng)對(duì)象的基類,在UIResponder類中定義了處理上述各種事件的接口鞋仍。我們熟悉的UIApplication常摧、 UIViewController、UIWindow和所有繼承自UIView的UIKit類都直接或間接的繼承自UIResponder威创,所以它們的實(shí)例都是可以構(gòu)成響應(yīng)者鏈的響應(yīng)者對(duì)象落午。


響應(yīng)者鏈1

響應(yīng)者鏈有以下特點(diǎn):

1、響應(yīng)者鏈通常是由視圖(UIView)構(gòu)成的肚豺;

2溃斋、一個(gè)視圖的下一個(gè)響應(yīng)者是它視圖控制器(UIViewController)(如果有的話),然后再轉(zhuǎn)給它的父視圖(Super View)吸申;

3梗劫、視圖控制器(如果有的話)的下一個(gè)響應(yīng)者為其管理的視圖的父視圖牍颈;

4陵像、單例的窗口(UIWindow)的內(nèi)容視圖將指向窗口本身作為它的下一個(gè)響應(yīng)者

需要指出的是,Cocoa Touch應(yīng)用不像Cocoa應(yīng)用材蛛,它只有一個(gè)UIWindow對(duì)象日丹,因此整個(gè)響應(yīng)者鏈要簡(jiǎn)單一點(diǎn)走哺;

5、單例的應(yīng)用(UIApplication)是一個(gè)響應(yīng)者鏈的終點(diǎn)聚凹,它的下一個(gè)響應(yīng)者指向nil割坠,以結(jié)束整個(gè)循環(huán)齐帚。


響應(yīng)者鏈2

三妒牙、事件分發(fā)(Event Delivery)

第一響應(yīng)者(First responder)指的是當(dāng)前接受觸摸的響應(yīng)者對(duì)象(通常是一個(gè)UIView對(duì)象),即表示當(dāng)前該對(duì)象正在與用戶交互对妄,它是響應(yīng)者鏈的開(kāi)端湘今。整個(gè)響應(yīng)者鏈和事件分發(fā)的使命都是找出第一響應(yīng)者。

UIWindow對(duì)象以消息的形式將事件發(fā)送給第一響應(yīng)者剪菱,使其有機(jī)會(huì)首先處理事件摩瞎。如果第一響應(yīng)者沒(méi)有進(jìn)行處理,系統(tǒng)就將事件(通過(guò)消息)傳遞給響應(yīng)者鏈中的下一個(gè)響應(yīng)者孝常,看看它是否可以進(jìn)行處理旗们。

iOS系統(tǒng)檢測(cè)到手指觸摸(Touch)操作時(shí)會(huì)將其打包成一個(gè)UIEvent對(duì)象,并放入當(dāng)前活動(dòng)Application的事件隊(duì)列构灸,單例的UIApplication會(huì)從事件隊(duì)列中取出觸摸事件并傳遞給單例的UIWindow來(lái)處理上渴,UIWindow對(duì)象首先會(huì)使用hitTest:withEvent:方法尋找此次Touch操作初始點(diǎn)所在的視圖(View),即需要將觸摸事件傳遞給其處理的視圖。

UIWindow實(shí)例對(duì)象會(huì)首先在它的內(nèi)容視圖上調(diào)用hitTest:withEvent:稠氮,此方法會(huì)在其視圖層級(jí)結(jié)構(gòu)中的每個(gè)視圖上調(diào)用pointInside:withEvent:(該方法用來(lái)判斷點(diǎn)擊事件發(fā)生的位置是否處于當(dāng)前視圖范圍內(nèi)曹阔,以確定用戶是不是點(diǎn)擊了當(dāng)前視圖),如果pointInside:withEvent:返回YES隔披,則繼續(xù)逐級(jí)調(diào)用赃份,直到找到touch操作發(fā)生的位置,這個(gè)視圖也就是要找的hit-test view奢米。


事件分發(fā)

hitTest:withEvent:方法的處理流程如下:

首先調(diào)用當(dāng)前視圖的pointInside:withEvent:方法判斷觸摸點(diǎn)是否在當(dāng)前視圖內(nèi)抓韩;

若返回NO,則hitTest:withEvent:返回nil;

若返回YES,則向當(dāng)前視圖的所有子視圖(subviews)發(fā)送hitTest:withEvent:消息,所有子視圖的遍歷順序是從最頂層視圖一直到到最底層視圖恃慧,即從subviews數(shù)組的末尾向前遍歷园蝠,直到有子視圖返回非空對(duì)象或者全部子視圖遍歷完畢;

若第一次有子視圖返回非空對(duì)象痢士,則hitTest:withEvent:方法返回此對(duì)象彪薛,處理結(jié)束;

如所有子視圖都返回非怠蹂,則hitTest:withEvent:方法返回自身(self)善延。


四、說(shuō)明

1城侧、如果最終hit-test沒(méi)有找到第一響應(yīng)者易遣,或者第一響應(yīng)者沒(méi)有處理該事件,則該事件會(huì)沿著響應(yīng)者鏈向上回溯嫌佑,如果UIWindow實(shí)例和UIApplication實(shí)例都不能處理該事件豆茫,則該事件會(huì)被丟棄。

2屋摇、hitTest:withEvent:方法將會(huì)忽略隱藏(hidden=YES)的視圖揩魂,禁止用戶操作(userInteractionEnabled=YES)的視圖,以及alpha級(jí)別小于0.01(alpha<0.01)的視圖炮温。如果一個(gè)子視圖的區(qū)域超過(guò)父視圖的bound區(qū)域(父視圖的clipsToBounds 屬性為NO火脉,這樣超過(guò)父視圖bound區(qū)域的子視圖內(nèi)容也會(huì)顯示),那么正常情況下對(duì)子視圖在父視圖之外區(qū)域的觸摸操作不會(huì)被識(shí)別,因?yàn)楦敢晥D的pointInside:withEvent:方法會(huì)返回NO,這樣就不會(huì)繼續(xù)向下遍歷子視圖了柒啤。當(dāng)然倦挂,也可以重寫(xiě)pointInside:withEvent:方法來(lái)處理這種情況。

3担巩、還可以重寫(xiě)hitTest:withEvent:來(lái)達(dá)到某些特定的目的方援。


五、實(shí)際運(yùn)用

?①如何尋找最合適的view

1.首先判斷主窗口(keyWindow)自己是否能接受觸摸事件

2.觸摸點(diǎn)是否在自己身上

3.從后往前遍歷子控件涛癌,重復(fù)前面的兩個(gè)步驟(首先查找數(shù)組中最后一個(gè)元素)

4.如果沒(méi)有符合條件的子控件犯戏,那么就認(rèn)為自己最合適處理


2個(gè)判斷方法

②攔截事件的處理

1.正因?yàn)閔itTest:withEvent:方法可以返回最合適的view窥浪,所以可以通過(guò)重寫(xiě)hitTest:withEvent:方法,返回指定的view作為最合適的view笛丙。

2.不管點(diǎn)擊哪里漾脂,最合適的view都是hitTest:withEvent:方法中返回的那個(gè)view。

3.通過(guò)重寫(xiě)hitTest:withEvent:胚鸯,就可以攔截事件的傳遞過(guò)程骨稿,想讓誰(shuí)處理事件誰(shuí)就處理事件。

事件傳遞給誰(shuí)姜钳,就會(huì)調(diào)用誰(shuí)的hitTest:withEvent:方法坦冠。

注 意:如果hitTest:withEvent:方法中返回nil,那么調(diào)用該方法的控件本身和其子控件都不是最合適的view哥桥,也就是在自己身上沒(méi)有找到更合適的view辙浑。那么最合適的view就是該控件的父控件。


六拟糕、總結(jié)

①事件的傳遞順序是這樣的:

產(chǎn)生觸摸事件->UIApplication事件隊(duì)列->[UIWindow hitTest:withEvent:]->返回更合適的view->[子控件 hitTest:withEvent:]->返回最合適的view

②事件的傳遞和響應(yīng)的區(qū)別:

事件的傳遞是從上到下(父控件到子控件)判呕,事件的響應(yīng)是從下到上(順著響應(yīng)者鏈條向上傳遞:子控件到父控件。

③特殊情況:

誰(shuí)都不能處理事件送滞,窗口也不能處理侠草。

重寫(xiě)window的hitTest:withEvent:方法return nil

只能有窗口處理事件。

控制器的view的hitTest:withEvent:方法return nil或者window的hitTest:withEvent:方法return self

如有問(wèn)題或疑問(wèn)歡迎留言交流犁嗅,一起進(jìn)步边涕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市褂微,隨后出現(xiàn)的幾起案子功蜓,更是在濱河造成了極大的恐慌,老刑警劉巖宠蚂,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件式撼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肥矢,警方通過(guò)查閱死者的電腦和手機(jī)端衰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)叠洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)甘改,“玉大人,你說(shuō)我怎么就攤上這事灭抑∈” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵腾节,是天一觀的道長(zhǎng)忘嫉。 經(jīng)常有香客問(wèn)我荤牍,道長(zhǎng),這世上最難降的妖魔是什么庆冕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任康吵,我火速辦了婚禮,結(jié)果婚禮上访递,老公的妹妹穿的比我還像新娘晦嵌。我一直安慰自己,他們只是感情好拷姿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布惭载。 她就那樣靜靜地躺著,像睡著了一般响巢。 火紅的嫁衣襯著肌膚如雪描滔。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天踪古,我揣著相機(jī)與錄音含长,去河邊找鬼。 笑死伏穆,一個(gè)胖子當(dāng)著我的面吹牛茎芋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蜈出,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼田弥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了铡原?” 一聲冷哼從身側(cè)響起偷厦,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎燕刻,沒(méi)想到半個(gè)月后只泼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卵洗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年请唱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片过蹂。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡十绑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酷勺,到底是詐尸還是另有隱情本橙,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布脆诉,位于F島的核電站甚亭,受9級(jí)特大地震影響贷币,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜亏狰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一役纹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧暇唾,春花似錦字管、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至抽活,卻和暖如春硫戈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背下硕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工丁逝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人梭姓。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓霜幼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親誉尖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子罪既,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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