iOS 响应链
首先要明確的是:在IOS中,有響應(yīng)者鏈對(duì)事件進(jìn)行響應(yīng),所有的響應(yīng)類都是UIResponder的子類,響應(yīng)者鏈?zhǔn)且粋€(gè)由不同對(duì)象組成的層次結(jié)構(gòu),其中的每個(gè)對(duì)象將依次獲得響應(yīng)事件消息的機(jī)會(huì)。
響應(yīng)鏈的過程:
當(dāng)事件發(fā)生的時(shí)候,響應(yīng)鏈?zhǔn)紫缺话l(fā)送給第一個(gè)響應(yīng)者(往往是事件發(fā)生的視圖,也就是用戶觸摸屏幕的地方)。事件將沿著響應(yīng)者鏈一直向下傳遞,知道被接受并作出處理。一般來說,第一響應(yīng)這是個(gè)視圖對(duì)象或者其子類,當(dāng)其被觸摸后事件就交由它處理,如果他不處理,時(shí)間就會(huì)被傳遞給視圖控制器對(duì)象UIViewController(如果存在),然后是它的俯視圖對(duì)象(superview),以此類推知道頂層視圖。接下來會(huì)沿著頂層視圖(top view)到窗口(UIwindow 對(duì)象) 再到程序的(UIApplication對(duì)象),如果整個(gè)過程都沒有響應(yīng)這個(gè)事件,則該事件被丟棄,一般情況下,在響應(yīng)鏈中只要有對(duì)象處理事件,事件就會(huì)被傳遞。
典型的響應(yīng)路線圖如:
First ?Responser --> The Window -->The Applicationn --> App Delegate
正常的響應(yīng)者鏈流程經(jīng)常被委托打斷,一個(gè)對(duì)象可能將響應(yīng)工作委托給另一個(gè)對(duì)象來完成(通常是視圖控制器viewcontroller)。
關(guān)于響應(yīng)鏈的常見問題:
1. 如何調(diào)用父類的controller中的方法:
[[self ?superview].nextResponder method]; 或者 [[[self ?superview] ?nextResponder ] ?method];?
這兩種方法都可以,但是使用的時(shí)候最好是進(jìn)行判斷一下:
?
id next = [self nextResponder]; while(![next isKindOfClass:[ViewController class]])//這里跳不出來。。。有人說這里跳不出來,其實(shí)是因?yàn)樗鼪]有當(dāng)前這個(gè)view放入ViewController中,自然也就跳不出來了,會(huì)死循環(huán),使用時(shí)需要注意。 { next = [next nextResponder]; } if ([next isKindOfClass:[ViewController class]]) { controller = (ViewController *)next; }?
?
2.當(dāng)一個(gè)子view需要接收點(diǎn)擊事件,其父view也需要接收點(diǎn)擊事件,該如何處理:
按照正常情況下,子類接收點(diǎn)擊事件以后,事件不會(huì)主動(dòng)傳遞到下一個(gè)響應(yīng)者,因此父類便不再接收點(diǎn)擊事件。如果子類不處理點(diǎn)擊事件,則事件會(huì)一直傳遞下去,直到UIApplication。
但是我們可以使得子類處理過響應(yīng)事件后仍將響應(yīng)這傳遞到下一個(gè)響應(yīng)者。但是我們編寫代碼才能辦到。
?
?
要做的如下: 子view的代碼如下: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 這里可以做子view自己想做的事,做完后,事件繼續(xù)上傳,就可以讓其父類,甚至父viewcontroller獲取到這個(gè)事件了[[selfnextResponder]touchesBegan:toucheswithEvent:event]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {[[selfnextResponder]touchesEnded:toucheswithEvent:event]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {[[selfnextResponder] touchesCancelled:toucheswithEvent:event]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {[[selfnextResponder] touchesMoved:toucheswithEvent:event]; }?
補(bǔ)充一段摘要:
?
摘取一部分說明:
“當(dāng)用戶 ?與 ?iPhone的觸摸屏 ?產(chǎn)生 ?互動(dòng)時(shí),硬件 ?就會(huì)探測(cè)到 ?物理接觸 ?并且 ?通知 ?操作系統(tǒng)。接著 ?操作系統(tǒng) ?就會(huì)創(chuàng)建 ?相應(yīng)的事件 ?并且 ?將 ?其 ?傳遞給 ?當(dāng)前正在運(yùn)行的應(yīng)用程序的事件隊(duì)列。然后 ?這項(xiàng)事件 ?會(huì)被事件循環(huán) ?傳遞給 ?優(yōu)先響應(yīng)者物件。優(yōu)先響應(yīng)者物件 ?是 ?事件 ?被觸發(fā)時(shí) ?和 ?用戶 ?交互的物件,比如 ?按鈕物件、視圖物件。如果 ?我們 ?編寫了 ?代碼 ?讓 ?優(yōu)先響應(yīng)者 ?處理 ?這種類型的事件,那么 ?它 ?就會(huì)處理 ?這種類型的事件。處理完 ?某項(xiàng)事件后,響應(yīng)者 ?有 ?兩個(gè)選項(xiàng):1、將 ?其 ?丟棄;2、將 ?其 ?傳遞給 ?響應(yīng)鏈條中的下一個(gè)響應(yīng)者。下一個(gè)響應(yīng)者的地址 ? 存儲(chǔ) ?在當(dāng)前響應(yīng)者物件所包含的變量nextResponder當(dāng)中。如果 ?優(yōu)先響應(yīng)者 ?無法處理 ?一項(xiàng)事件,那么 ?這項(xiàng)事件 ?就傳遞給 ?下一個(gè)響應(yīng)者,直到 ?這項(xiàng)事件 ?到達(dá) ?能處理它的響應(yīng)者 ?或者 ?到達(dá) ?響應(yīng)鏈條的末端,也就是 ?UIApplication類型的物件。UIApplication類型的物件 ?收到 ?一項(xiàng)事件后,也是 ?要么 ?處理,要么 ?丟棄。“
比如 ?有 ?一個(gè)視圖物件,這個(gè)視圖物件上 ?有 ?一個(gè)按鈕物件。當(dāng)用戶 ?觸摸 ?這個(gè)按鈕物件時(shí),作為優(yōu)先響應(yīng)者,這個(gè)按鈕物件 ?就會(huì)收到 ?一項(xiàng)事件。如果 ?這個(gè)按鈕物件 ?無法處理 ?這項(xiàng)事件,就會(huì)將 ?這項(xiàng)事件 ?傳遞給 ?視圖物件。如果 ?視圖物件 ?無法處理 ?這項(xiàng)事件,就會(huì)將 ?這項(xiàng)事件 ?傳遞給 ?視圖控制器物件。以此類推。
應(yīng)該注意的 ?是 ?當(dāng)我們 ?在使用 ?響應(yīng)鏈條時(shí),一項(xiàng)事件 ?并不會(huì)自動(dòng)地 ?從一個(gè)響應(yīng)者 ?傳遞到 ?下一個(gè)響應(yīng)者。如果 ?要將 ?一項(xiàng)事件 ?從一個(gè)響應(yīng)者 ?傳遞到 ?下一個(gè)響應(yīng)者,我們 ?必須編寫 ?代碼 ?才能辦到。”
轉(zhuǎn)載于:https://www.cnblogs.com/jiangu66/archive/2013/04/23/3037387.html
總結(jié)
- 上一篇: (R)?ex 0.41.2 发布,软件配
- 下一篇: 腾讯2013暑期实习笔试面试总结