iOS事件處理-響應(yīng)者和響應(yīng)者鏈

原文地址:https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/understanding_event_handling_responders_and_the_responder_chain
如原作者發(fā)現(xiàn)有侵權(quán)行為可責(zé)令我在24小時(shí)之內(nèi)刪除摊溶,前提是你能看到杖狼。
翻譯者:毛毛可


學(xué)習(xí)事件是怎樣在你的app中傳遞的,并學(xué)會(huì)應(yīng)該如何處理它們.

Apps使用responder(響應(yīng)者對(duì)象)對(duì)象來(lái)接受并處理事件.一個(gè)responder對(duì)象可以是任意一個(gè)UIResponder類的實(shí)例,其中包括其子類UIView,UIViewController和UIApplication.

responder對(duì)象在接收到原始的事件對(duì)象,必須處理它或者將它繼續(xù)向前傳遞給下一個(gè)responder對(duì)象.當(dāng)你的app在接收到一個(gè)事件時(shí),UIKit框架會(huì)自動(dòng)的找到最合適的responder去處理該事件,這就是第一響應(yīng)者.

未處理的事件會(huì)在響應(yīng)者鏈中從這個(gè)responder傳遞給下一個(gè)responder.事實(shí)上你的app中沒(méi)有單獨(dú)的響應(yīng)者鏈.UIkit定義了responder傳遞的默認(rèn)規(guī)則,當(dāng)然你可以通過(guò)覆蓋responder對(duì)象中對(duì)應(yīng)的屬性來(lái)更改規(guī)則.

圖一

圖一 顯示了一條默認(rèn)的響應(yīng)者鏈,包括一個(gè)label,一個(gè)text field,一個(gè)button和兩個(gè)background view.如果text field不去處理事件,那么UIKit會(huì)將事件發(fā)送給textfield的父視圖對(duì)象.接著就是window的root view.從root view出來(lái),會(huì)順著響應(yīng)者鏈在到達(dá)window對(duì)象之前先傳遞給view controller.如果此時(shí)window也不處理此事件,UIKit會(huì)將事件分發(fā)給UIApplication對(duì)象,或者是分發(fā)給app delegate,app delegate是一個(gè)UIResponder實(shí)例,但此過(guò)程已經(jīng)不是響應(yīng)者鏈中的一部分了.

確定事件的第一響應(yīng)者

針對(duì)每種類型的事件,UIKit指定了第一響應(yīng)者,將事件發(fā)送給第一響應(yīng)者.第一響應(yīng)者的確定是基于事件的類型的.

Touch事件
第一響應(yīng)者就是觸摸發(fā)生的view.

Press事件
第一響應(yīng)者是注冊(cè)了focus的響應(yīng)者對(duì)象.

搖動(dòng)事件
第一響應(yīng)者是你指定的相應(yīng)對(duì)象.

遠(yuǎn)程控制事件
第一響應(yīng)者是你指定的相應(yīng)對(duì)象.

編輯菜單信息
第一響應(yīng)者是你指定的相應(yīng)對(duì)象.

Note
運(yùn)動(dòng)事件相關(guān)的加速,陀螺儀和磁力計(jì)都不會(huì)出現(xiàn)在響應(yīng)者鏈中.Core MOtion會(huì)派發(fā)這些事件給你對(duì)應(yīng)注冊(cè)的對(duì)象.

UIControl控件會(huì)直接通過(guò)相關(guān)聯(lián)的target-action傳送事件.
當(dāng)界面中的是UIControl控件時(shí),UIControl會(huì)調(diào)用target對(duì)象的action方法,或者說(shuō)返送一個(gè)action消息給其target對(duì)象.
action消息不是一個(gè)事件,但是依然可以利用響應(yīng)者鏈.當(dāng)UIControl對(duì)象的target為nil時(shí),UIKit開(kāi)始從target對(duì)象并順著響應(yīng)者鏈找,直到找到一個(gè)實(shí)現(xiàn)了相關(guān)action方法的對(duì)象.舉例,UIKit editing menu使用這種行為去搜索對(duì)應(yīng)responder對(duì)象的相關(guān)實(shí)現(xiàn)方法比如cut:,copy:或者paste:.

如果在view中有附加的手勢(shì)識(shí)別器,手勢(shì)識(shí)別器會(huì)在在view之前接收到touch和press事件.如果view中所有的手勢(shì)識(shí)別都沒(méi)有識(shí)別成功,事件會(huì)傳給view去處理.如果此view沒(méi)有處理它們,UIKit會(huì)繼續(xù)傳給響應(yīng)者鏈的上一層.關(guān)于更多的手勢(shì)識(shí)別器處理事件,請(qǐng)參考UIKit Gestures.

確定哪個(gè)Responder包含Touch事件

UIKit使用 基于view的hit-testing方式去確定touch事件發(fā)生的位置.具體來(lái)說(shuō),UIKit會(huì)將touch的位置與在view層級(jí)中的view對(duì)象的容器范圍比較.UIView的hitTest:withEvent:方法隨著view層級(jí),查找包含touch的最深層的子view.這個(gè)view將成為touch事件的第一響應(yīng)者.

Note
如果touch的位置超出了view的范圍,hitTest:withEvent:方法會(huì)忽略此view及其所有子view.因此,當(dāng)view的clipsToBounds屬性為NO時(shí),即使包含了touch,超出view范圍的子view也不會(huì)有效.更多關(guān)于hitTest:withEvent:方法的行為,請(qǐng)查看view的hitTest:withEvent:方法.

UIkit總會(huì)賦值給view其范圍范圍的每個(gè)touch.當(dāng)觸摸發(fā)生時(shí),UIKit創(chuàng)建UITouch對(duì)象,直到觸摸結(jié)束后才釋放touch對(duì)象.如果觸摸的位置或者其他參數(shù)改變了,UIKit會(huì)及時(shí)更新UITouch對(duì)象的信息.只有一個(gè)屬性不可能發(fā)生改變就是是否在view范圍中.及時(shí)當(dāng)觸摸位置移出了原view,touch對(duì)象的屬性也不會(huì)改變.

改變響應(yīng)者鏈

你可以通過(guò)重載responder對(duì)象的nextResponder屬性來(lái)改變響應(yīng)者鏈.你可以在此方法(getter)返回下一個(gè)響應(yīng)者.

許多UIKit的類已經(jīng)重載了這個(gè)屬性,返回了指定的對(duì)象.

UIView對(duì)象,如果view是view controll的根視圖,那么view的下個(gè)響應(yīng)者就是view controller,否者下一個(gè)響應(yīng)者就是view的父視圖.

UIViewController對(duì)象.
如果一個(gè)vc是被另一個(gè)vcpresent出來(lái)的,那么vc的下一個(gè)響應(yīng)者就是present它出來(lái)的那個(gè)vc
如果window的根視圖是view controller.view,那么view controller的下一個(gè)響應(yīng)者就是window對(duì)象.

window對(duì)象.window的下一個(gè)responder是UIApplication對(duì)象.

UIApplication對(duì)象.下一個(gè)響應(yīng)者是app delegate.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颈畸,一起剝皮案震驚了整個(gè)濱河市乌奇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眯娱,老刑警劉巖礁苗,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異徙缴,居然都是意外死亡试伙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)于样,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)疏叨,“玉大人,你說(shuō)我怎么就攤上這事穿剖≡槁” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵糊余,是天一觀的道長(zhǎng)秀又。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贬芥,這世上最難降的妖魔是什么吐辙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮誓军,結(jié)果婚禮上袱讹,老公的妹妹穿的比我還像新娘。我一直安慰自己昵时,他們只是感情好捷雕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著壹甥,像睡著了一般救巷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上句柠,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天浦译,我揣著相機(jī)與錄音,去河邊找鬼溯职。 笑死精盅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谜酒。 我是一名探鬼主播叹俏,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼僻族!你這毒婦竟也來(lái)了粘驰?” 一聲冷哼從身側(cè)響起屡谐,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝌数,沒(méi)想到半個(gè)月后愕掏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顶伞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年饵撑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枝哄。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肄梨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挠锥,到底是詐尸還是另有隱情众羡,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布蓖租,位于F島的核電站粱侣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蓖宦。R本人自食惡果不足惜齐婴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稠茂。 院中可真熱鬧柠偶,春花似錦、人聲如沸睬关。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)电爹。三九已至蔫仙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丐箩,已是汗流浹背摇邦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屎勘,地道東北人施籍。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像概漱,于是被迫代替她去往敵國(guó)和親丑慎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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

  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的?困惑于Cell怎么突然不能點(diǎn)擊了立哑?糾結(jié)于如何實(shí)現(xiàn)這個(gè)奇葩響應(yīng)需求?亦或是...
    Lotheve閱讀 56,833評(píng)論 51 598
  • 在iOS開(kāi)發(fā)中經(jīng)常會(huì)涉及到觸摸事件姻灶。本想自己總結(jié)一下铛绰,但是遇到了這篇文章,感覺(jué)總結(jié)的已經(jīng)很到位产喉,特此轉(zhuǎn)載捂掰。作者:L...
    WQ_UESTC閱讀 5,995評(píng)論 4 26
  • 在開(kāi)發(fā)過(guò)程中,大家或多或少的都會(huì)碰到令人頭疼的手勢(shì)沖突問(wèn)題曾沈,正好前兩天碰到一個(gè)類似的bug这嚣,于是借著這個(gè)機(jī)會(huì)了解了...
    閆仕偉閱讀 5,303評(píng)論 2 23
  • 重點(diǎn)參考鏈接: View Programming Guide for iOS https://developer....
    Kevin_Junbaozi閱讀 4,409評(píng)論 0 15
  • 一. Hit-Testing 什么是Hit-Testing?對(duì)于觸摸事件, window首先會(huì)嘗試將事件交給事件觸...
    面糊閱讀 817評(píng)論 0 50