事件傳遞:響應(yīng)者鏈條(譯)

當(dāng)你設(shè)計(jì)你的應(yīng)用程序時(shí)嗡靡,你可能需要?jiǎng)討B(tài)的響應(yīng)事件焚刺。例如匪蝙,一個(gè)觸摸事件可以由屏幕上的很多對(duì)象產(chǎn)生主籍,你必須決定由哪個(gè)對(duì)象響應(yīng)對(duì)應(yīng)的事件和明白該對(duì)象如何接收到事件的。

當(dāng)用戶產(chǎn)生了一個(gè)事件逛球,UIKit創(chuàng)建了一個(gè)包含處理事件所需信息的事件對(duì)象千元。然后把這個(gè)事件對(duì)象放置在全局事件隊(duì)列。對(duì)于觸摸事件颤绕,會(huì)被包裝成一個(gè)UIEvent對(duì)象幸海。對(duì)于動(dòng)作事件,會(huì)根據(jù)你所使用的框架和你感興趣的動(dòng)作事件而有所不同奥务。

一個(gè)事件沿著一個(gè)具體的路徑向前傳遞物独,直到有一個(gè)對(duì)象可以對(duì)其進(jìn)行處理。首先氯葬,

UIApplication單例對(duì)象會(huì)從事件隊(duì)列里獲取一個(gè)事件并把它分發(fā)挡篓,一貫地將事件發(fā)送到應(yīng)用的key window對(duì)象,key window對(duì)象會(huì)把事件傳遞到原始對(duì)象進(jìn)行處理帚称,原始對(duì)象會(huì)根據(jù)事件的類型而有所不同官研。

· 觸摸事件。對(duì)于觸摸事件闯睹,window對(duì)象首先會(huì)嘗試傳遞事件到產(chǎn)生觸摸事件的視圖戏羽。這個(gè)視圖被稱為hit-test視圖,尋找hit-test視圖的過程被稱為hit-testing楼吃。

· 動(dòng)作和遠(yuǎn)程控制事件始花。window對(duì)象會(huì)把搖一搖動(dòng)作或者遠(yuǎn)程控制事件發(fā)送到第一響應(yīng)者進(jìn)行處理。

這些事件路徑的最終目標(biāo)是尋找一個(gè)對(duì)象可以處理和相應(yīng)一個(gè)事件所刀。因此,UIKit首先會(huì)事件發(fā)送到最適合處理該事件的對(duì)象捞挥。最適合處理觸摸事件的對(duì)象就是hit-test視圖浮创,對(duì)于其他事件,對(duì)象就是第一響應(yīng)者砌函。接下來的部分會(huì)詳細(xì)展開hit-test視圖和第一響應(yīng)者對(duì)象是如何被確認(rèn)的斩披。

Hit-Testing返回觸摸事件發(fā)生的視圖

iOS利用hit-tesing尋找被觸摸的視圖溜族。hit-tesing需要檢查一個(gè)觸摸事件是否在相關(guān)的視圖對(duì)象的范圍內(nèi),如果是垦沉,它會(huì)遞歸地檢查這個(gè)視圖對(duì)象的所有子視圖煌抒。處于視圖層級(jí)中包含觸摸點(diǎn)的最底層視圖就會(huì)成為hit-test視圖。當(dāng)iOS確定hit-test視圖后厕倍,它會(huì)把觸摸事件拋給這個(gè)視圖去處理寡壮。

例如,假如用戶觸摸視圖E(圖2-1)讹弯。iOS通過以下順序從子視圖中找出hit-test視圖

1.觸摸點(diǎn)在視圖A里面况既,所以會(huì)檢查子視圖B和C。

2.觸摸點(diǎn)不在視圖B的范圍內(nèi)组民,但是在視圖C的范圍內(nèi)棒仍,所以它會(huì)檢查子視圖D和E。

3.觸摸點(diǎn)不在視圖D臭胜,但在視圖E的范圍內(nèi)莫其。

視圖E是在視圖層級(jí)中包含觸摸點(diǎn)的最底層視圖,所以它就成為了hit-test視圖

(圖2-1)

(hitTest:withEvent:)方法返回一個(gè)給定CGPoint和UIEvent的hit-test視圖耸三。(hitTest:withEvent:)方法通過(pointInside:withEvent:)方法調(diào)用乱陡。如果一個(gè)點(diǎn)通過(hitTest:withEvent:)方法判斷是在視圖的范圍內(nèi),(pointInside:withEvent:)方法就會(huì)返回YES吕晌。然后這個(gè)方法就會(huì)在返回YES的子視圖上面遞歸地調(diào)用(hitTest:withEvent:)方法蛋褥。

如果這個(gè)點(diǎn)通過(hitTest:withEvent:)方法判斷不在視圖的范圍內(nèi),最先調(diào)用的(pointInside:withEvent:)方法就會(huì)返回NO睛驳。這個(gè)點(diǎn)被忽略了烙心,(hitTest:withEvent:)方法就會(huì)返回nil。如果一個(gè)子視圖返回NO乏沸,那么在視圖層級(jí)中整個(gè)分支都會(huì)被忽略淫茵,因?yàn)槿绻@個(gè)觸摸點(diǎn)不在這個(gè)視圖中產(chǎn)生,那么也不會(huì)再這個(gè)視圖的子視圖中產(chǎn)生蹬跃。這就意味著一些在父視圖外的子視圖的點(diǎn)不能接收到觸摸事件匙瘪,因?yàn)橛|摸點(diǎn)必須在父視圖和子視圖的范圍內(nèi)。子視圖的范圍超出父視圖的情況會(huì)發(fā)生在子視圖的clipsToBounds屬性被設(shè)為NO蝶缀。

注意:一個(gè)觸摸對(duì)象的生命周期會(huì)跟它的hit-test密切關(guān)聯(lián)丹喻,即使后來觸摸移到view的外面。

hit-test視圖有第一次機(jī)會(huì)去處理一個(gè)觸摸事件翁都。如果hit-test視圖不能處理一個(gè)事件碍论,這個(gè)事件就會(huì)在視圖的響應(yīng)者鏈條上傳遞,直到系統(tǒng)找到一個(gè)可以找到該事件的對(duì)象柄慰。

響應(yīng)者鏈條由響應(yīng)者對(duì)象組成

很多類型的事件依賴一個(gè)響應(yīng)者鏈條進(jìn)行傳遞鳍悠。響應(yīng)者鏈條是一系列的響應(yīng)者對(duì)象税娜。由第一個(gè)響應(yīng)者開始,并由application對(duì)象結(jié)束藏研。如果第一響應(yīng)者不能處理一個(gè)事件敬矩,事件會(huì)向前傳遞給響應(yīng)者鏈條的下一個(gè)響應(yīng)者。

響應(yīng)者對(duì)象是一個(gè)可以處理事件的對(duì)象蠢挡。UIResponder類是所有響應(yīng)者對(duì)象的基類弧岳,它定義的程序接口不只是為了事件的處理,而且為了普通的響應(yīng)者行為袒哥。UIApplication,UIViewController和UIView的實(shí)例都可以成為響應(yīng)者缩筛,意味著所有的視圖和很多的關(guān)鍵控制器對(duì)象都可以是響應(yīng)者。注意:核心動(dòng)畫圖層都不可以成為響應(yīng)者堡称。

首先由第一響應(yīng)者接收事件瞎抛。一般的,第一項(xiàng)響應(yīng)者是一個(gè)視圖對(duì)象却紧。一個(gè)對(duì)象通過以下兩種方式成為第一響應(yīng)者:

1桐臊、復(fù)寫(canBecomeFirstResponder)方法并返回YES。

2晓殊、接收一個(gè)(becomFirstResponder)信息断凶。如果有必要,一個(gè)對(duì)象可以發(fā)送這條信息給它自己巫俺。

注意:一個(gè)對(duì)象成為第一響應(yīng)者前確保應(yīng)用已經(jīng)把這個(gè)對(duì)象的圖層渲染出來认烁。例如,我們一般在(viewDidAppear:)方法里面調(diào)用(becomeFirstResponder)方法介汹,如果嘗試在(viewWillAppear:)方法里面分配第一響應(yīng)者却嗡,對(duì)象的圖層還沒有渲染出來,所以(becomeFirstResponder)方法就會(huì)返回NO嘹承。

事件不是唯一的依賴響應(yīng)者鏈條的對(duì)象窗价。響應(yīng)者鏈條被用于以下的情況:

· 觸摸事件。如果hit-test視圖不能處理一個(gè)觸摸事件叹卷,那么這個(gè)事件就會(huì)從hit-test視圖開始沿著響應(yīng)者鏈條傳遞撼港。

· 動(dòng)作事件。通過UIKit來處理搖一搖動(dòng)作事件骤竹,第一響應(yīng)者必須實(shí)現(xiàn)UIResponder類的(motionBegan:withEvent:)方法或者(motionEnded:withEvent:)方法之一帝牡。

· 遠(yuǎn)程控制事件。第一響應(yīng)者處理遠(yuǎn)程控制事件必須實(shí)現(xiàn)UIResponder類的(remoteControlReceivedWithEvent:)方法蒙揣。

· 動(dòng)作信息靶溜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鸣奔,隨后出現(xiàn)的幾起案子墨技,更是在濱河造成了極大的恐慌,老刑警劉巖挎狸,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扣汪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡锨匆,警方通過查閱死者的電腦和手機(jī)崭别,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恐锣,“玉大人茅主,你說我怎么就攤上這事⊥亮瘢” “怎么了诀姚?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)玷禽。 經(jīng)常有香客問我赫段,道長(zhǎng),這世上最難降的妖魔是什么矢赁? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任糯笙,我火速辦了婚禮箕戳,結(jié)果婚禮上箱靴,老公的妹妹穿的比我還像新娘。我一直安慰自己驶拱,他們只是感情好额获,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布够庙。 她就那樣靜靜地躺著,像睡著了一般咪啡。 火紅的嫁衣襯著肌膚如雪首启。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天撤摸,我揣著相機(jī)與錄音毅桃,去河邊找鬼。 笑死准夷,一個(gè)胖子當(dāng)著我的面吹牛钥飞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衫嵌,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼读宙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了楔绞?” 一聲冷哼從身側(cè)響起结闸,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤唇兑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后桦锄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扎附,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年结耀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了留夜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡图甜,死狀恐怖碍粥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黑毅,我是刑警寧澤嚼摩,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站矿瘦,受9級(jí)特大地震影響低斋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匪凡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一膊畴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧病游,春花似錦唇跨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滋尉,卻和暖如春玉控,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狮惜。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工高诺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碾篡。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓虱而,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親开泽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牡拇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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

  • 用戶以多種方式操縱他們的iOS設(shè)備,例如觸摸屏幕或搖動(dòng)設(shè)備。 iOS會(huì)解釋用戶何時(shí)以及如何操作硬件并將此信息傳遞到...
    坤坤同學(xué)閱讀 3,997評(píng)論 7 19
  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的惠呼?困惑于Cell怎么突然不能點(diǎn)擊了导俘?糾結(jié)于如何實(shí)現(xiàn)這個(gè)奇葩響應(yīng)需求?亦或是...
    Lotheve閱讀 57,183評(píng)論 51 599
  • 在iOS開發(fā)中經(jīng)常會(huì)涉及到觸摸事件剔蹋。本想自己總結(jié)一下趟畏,但是遇到了這篇文章,感覺總結(jié)的已經(jīng)很到位滩租,特此轉(zhuǎn)載。作者:L...
    WQ_UESTC閱讀 6,013評(píng)論 4 26
  • 本文來自:http://ios.jobbole.com/84081/ 前言: 按照時(shí)間順序利朵,事件的生命周期是這樣的...
    HackerOnce閱讀 2,840評(píng)論 1 10
  • 事件傳遞:響應(yīng)者鏈 當(dāng)你設(shè)計(jì)一個(gè)app的時(shí)候律想,你很可能需要你的app能夠動(dòng)態(tài)響應(yīng)某些事件。比如绍弟,觸摸可以發(fā)生在屏幕...
    hjfrun閱讀 1,033評(píng)論 1 5