響應(yīng)者與響應(yīng)者鏈(上)

網(wǎng)上很多關(guān)于這方面的文章腺办,但是決定還是如何使用響應(yīng)者和響應(yīng)者鏈出發(fā)迟蜜,然后來解釋一波兒义矛,首先推薦去看官方文章Using Responders and the Responder Chain to Handle Events

本篇是對(duì)文章的翻譯

概述

應(yīng)用程序使用響應(yīng)對(duì)象接收和處理事件。UIResponder谊娇。類的任何實(shí)例對(duì)象都是響應(yīng)者类垫,公共子類包括UIView,UIViewController,UIApplication,響應(yīng)者接收原始事件數(shù)據(jù)惹悄,并且必須處理事件或?qū)⑵滢D(zhuǎn)發(fā)給另一個(gè)響應(yīng)者對(duì)象。 當(dāng)您的應(yīng)用收到事件時(shí)肩钠,UIKit會(huì)自動(dòng)將該事件定向到最合適的響應(yīng)者對(duì)象泣港,稱為第一響應(yīng)者。未處理的事件從響應(yīng)者傳遞到活動(dòng)響應(yīng)者鏈中的響應(yīng)者价匠,這是應(yīng)用程序的響應(yīng)者對(duì)象的動(dòng)態(tài)配置当纱。 圖1顯示了應(yīng)用程序中的響應(yīng)者,其界面包含label踩窖,文本 text field坡氯,button兩個(gè)background views。 該圖還顯示了事件如何在響應(yīng)者鏈之后從一個(gè)響應(yīng)者移動(dòng)到下一個(gè)響應(yīng)者洋腮。

圖 1 Responder chains in an app.png

如果text field不處理事件箫柳,UIKit會(huì)將事件發(fā)送到文本字段的父UIView對(duì)象,然后是window的根視圖啥供。 從根視圖開始悯恍,響應(yīng)器鏈在將事件定向到窗口之前轉(zhuǎn)移到擁有的視圖控制器。 如果window無法處理事件伙狐,UIKit會(huì)將事件傳遞給UIApplication對(duì)象涮毫,如果該對(duì)象是UIResponder的實(shí)例而不是響應(yīng)者鏈的一部分,則可能傳遞給app delegate贷屎。

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

UIKit根據(jù)事件的類型將對(duì)象指定為事件的第一響應(yīng)者罢防。 事件類型包括:

事件類型.png

  • 觸摸事件(Touch events):第一響應(yīng)者是觸摸點(diǎn)所在的視圖。
  • 按壓事件(Press events):第一響應(yīng)者是有焦點(diǎn)的響應(yīng)者唉侄。
  • 搖晃運(yùn)動(dòng)事件(Shake-motion events):第一響應(yīng)者是由我們自己(或者UIKit)指定為第一響應(yīng)者的對(duì)象咒吐。
  • 遠(yuǎn)程控制事件(Remote-control events):第一響應(yīng)者是由我們自己(或者UIKit)指定為第一響應(yīng)者的對(duì)象。
  • 編輯菜單消息(Editing menu messages):第一響應(yīng)者是由我們自己(或者UIKit)指定為第一響應(yīng)者的對(duì)象。

注意:與加速計(jì)渤滞、陀螺儀和磁力計(jì)相關(guān)的運(yùn)動(dòng)事件不遵循響應(yīng)者鏈,Core Motion會(huì)將這些事件直接傳遞給我們指定的對(duì)象榴嗅。有關(guān)更多信息妄呕,可以參看Core Motion Framework

控件使用動(dòng)作消息直接與其關(guān)聯(lián)的目標(biāo)對(duì)象進(jìn)行通信嗽测。 當(dāng)用戶與控件交互時(shí)绪励,控件會(huì)向其target對(duì)象發(fā)送操作消息。 動(dòng)作消息不是事件唠粥,但它們?nèi)匀豢梢岳庙憫?yīng)者鏈疏魏。 當(dāng)控件的target對(duì)象為nil時(shí),UIKittarget對(duì)象開始并遍歷響應(yīng)者鏈晤愧,直到找到實(shí)現(xiàn)相應(yīng)操作方法的對(duì)象大莫。 例如,UIKit編輯菜單使用此行為來搜索響應(yīng)器對(duì)象官份,這些對(duì)象實(shí)現(xiàn)具有cut:只厘,copy:paste:等名稱的方法。
手勢(shì)識(shí)別器在其視圖之前接收touchpress事件舅巷。 如果視圖的手勢(shì)識(shí)別器無法識(shí)別觸摸序列羔味,則UIKit會(huì)將touch發(fā)送到視圖。 如果視圖沒有處理touch钠右,UIKit會(huì)將它們傳遞給響應(yīng)者鏈赋元。 有關(guān)使用手勢(shì)識(shí)別器處理事件的更多信息,請(qǐng)參閱處理UIKit手勢(shì)飒房。

確定哪個(gè)響應(yīng)者包含touch事件

UIKit使用基于視圖的hit-testing來確定$touch事件發(fā)生的位置搁凸。 具體來說,UIKittouch位置與視圖層次結(jié)構(gòu)中視圖對(duì)象的邊界進(jìn)行比較情屹。
UIViewhitTest:withEvent: 方法遍歷視圖層次結(jié)構(gòu)坪仇,查找包含指定觸摸(touch)的最深子視圖,該子視圖成為觸摸事件的第一個(gè)響應(yīng)者垃你。

觸摸發(fā)生時(shí)椅文,UIKit會(huì)創(chuàng)建一個(gè)UITouch對(duì)象并將其與視圖關(guān)聯(lián)。 當(dāng)觸摸位置或其他參數(shù)發(fā)生變化時(shí)惜颇,UIKit會(huì)使用新信息更新相同的UITouch對(duì)象皆刺。 唯一不改變的屬性是視圖。 (即使觸摸位置移動(dòng)到原始視圖之外凌摄,觸摸視圖屬性中的值也不會(huì)改變羡蛾。)觸摸結(jié)束時(shí),UIKit會(huì)釋放UITouch對(duì)象锨亏。

hitTest:withEvent: 方法介紹

  1. 如果觸摸位置位于視圖邊界之外痴怨,則hitTest:withEvent:方法將忽略該視圖及其所有子視圖忙干。 因此,當(dāng)視圖的clipsToBounds屬性為NO時(shí)浪藻,即使它們恰好包含觸摸捐迫,也不會(huì)返回該視圖邊界之外的子視圖。
    2.hitTest:withEvent:方法會(huì)遍歷當(dāng)前視圖層爱葵,并調(diào)用每個(gè)子視圖的pointInside:withEvent:方法來判斷子視圖的邊界是否包含觸摸點(diǎn)施戴。如果pointInside:withEvent:返回YES,則會(huì)同樣遍歷子視圖的視圖層萌丈,直到找到包含指定點(diǎn)的最上層的視圖赞哗。如果視圖不包含該觸摸點(diǎn),就忽略此視圖層次結(jié)構(gòu)的分支辆雾。因此我們可以覆override hitTest:withEvent以隱藏子視圖中的觸摸事件肪笋。
  2. 此方法忽略掉被隱藏,禁用用戶交互或alpha級(jí)別小于0.01的視圖對(duì)象度迂。在確定命中時(shí)涂乌,此方法不會(huì)考慮視圖的內(nèi)容。因此英岭,即使指定的點(diǎn)位于該視圖內(nèi)容的透明部分湾盒,仍然可以返回視圖。
    位于接收者界限之外的點(diǎn)永遠(yuǎn)不會(huì)被報(bào)告為命中诅妹,即使它們實(shí)際上位于接收者的子視圖中罚勾。如果當(dāng)前視圖的clipsToBounds屬性設(shè)置為NO并且受影響的子視圖超出視圖的邊界,hitTest:withEvent:方法也不會(huì)返回命中了此視圖吭狡。

改變響應(yīng)者鏈

您可以通過覆蓋響應(yīng)程序?qū)ο蟮?code>nextResponder屬性來更改響應(yīng)程序鏈尖殃。 執(zhí)行此操作時(shí),下一個(gè)響應(yīng)者是您返回的對(duì)象划煮。
許多UIKit類已經(jīng)覆蓋此屬性并返回特定對(duì)象送丰,包括:

  • \color{MediumVioletRed}{ UIView}對(duì)象。 如果視圖是視圖控制器的根視圖弛秋,則下一個(gè)響應(yīng)者是視圖控制器; 否則器躏,下一個(gè)響應(yīng)者是視圖的父視圖。
  • UIViewController對(duì)象蟹略。
    如果視圖控制器的視圖是window的根視圖登失,則下一個(gè)響應(yīng)者是window object
    如果視圖控制器由另一個(gè)視圖控制器呈現(xiàn)挖炬,則下一個(gè)響應(yīng)者是呈現(xiàn)視圖控制器揽浙。
  • UIWindow對(duì)象。 窗口的下一個(gè)響應(yīng)者是UIApplication對(duì)象。
  • UIApplication對(duì)象馅巷。 下一個(gè)響應(yīng)者是 UIApplication膛虫,但僅當(dāng)應(yīng)用程序委托是UIResponder的實(shí)例且不是視圖,視圖控制器或應(yīng)用程序?qū)ο蟊旧頃r(shí)钓猬。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末走敌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子逗噩,更是在濱河造成了極大的恐慌,老刑警劉巖跌榔,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件异雁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡僧须,警方通過查閱死者的電腦和手機(jī)纲刀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來担平,“玉大人示绊,你說我怎么就攤上這事≡萋郏” “怎么了面褐?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長取胎。 經(jīng)常有香客問我展哭,道長,這世上最難降的妖魔是什么闻蛀? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任匪傍,我火速辦了婚禮,結(jié)果婚禮上觉痛,老公的妹妹穿的比我還像新娘役衡。我一直安慰自己,他們只是感情好薪棒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布手蝎。 她就那樣靜靜地躺著,像睡著了一般俐芯。 火紅的嫁衣襯著肌膚如雪柑船。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天泼各,我揣著相機(jī)與錄音鞍时,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛逆巍,可吹牛的內(nèi)容都是我干的及塘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锐极,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼笙僚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起灵再,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤肋层,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后翎迁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栋猖,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年汪榔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒲拉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痴腌,死狀恐怖雌团,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情士聪,我是刑警寧澤锦援,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站剥悟,受9級(jí)特大地震影響雨涛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜懦胞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一替久、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躏尉,春花似錦蚯根、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至教藻,卻和暖如春距帅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背括堤。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工碌秸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绍移,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓讥电,卻偏偏與公主長得像蹂窖,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恩敌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • 概述 應(yīng)用程序使用響應(yīng)者對(duì)象來接收和處理事件纠炮,屬于UIResponder類的實(shí)例對(duì)象都是響應(yīng)者月趟,常見的子類包括UI...
    漸z閱讀 2,657評(píng)論 0 3
  • 用戶以多種方式操縱他們的iOS設(shè)備,例如觸摸屏幕或搖動(dòng)設(shè)備恢口。 iOS會(huì)解釋用戶何時(shí)以及如何操作硬件并將此信息傳遞到...
    坤坤同學(xué)閱讀 3,997評(píng)論 7 19
  • 在iOS開發(fā)中經(jīng)常會(huì)涉及到觸摸事件孝宗。本想自己總結(jié)一下,但是遇到了這篇文章弧蝇,感覺總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載折砸。作者:L...
    WQ_UESTC閱讀 6,011評(píng)論 4 26
  • 翻譯自“View Controller Programming Guide for iOS”看疗。 1 定義子類 使用...
    lakerszhy閱讀 2,398評(píng)論 0 5
  • 事件傳遞:響應(yīng)者鏈 當(dāng)你設(shè)計(jì)一個(gè)app的時(shí)候,你很可能需要你的app能夠動(dòng)態(tài)響應(yīng)某些事件睦授。比如两芳,觸摸可以發(fā)生在屏幕...
    hjfrun閱讀 1,033評(píng)論 1 5