iOS學習筆記6 – 第一響應對象初涉(First Responder)

來源:互聯網
上載者:User

終於苦等到了iOS項目,把PHP項目移交了。但iOS學習停滯了那麼長時間大丈夫?不管了,先惡補兩天吧,能看到哪裡就是哪裡,然後邊做邊學。

 

今天學了下前台UI,就來說下響應對象(Responder Object)吧。之所以說初涉,是看到教程後面的章節還會涉及觸摸,暫時沒學到就不寫了。

 

1. UIResonder

對於C#裡所有的控制項(例如TextBox),都繼承於Control類。而Control類的繼承關係如下:

System.Object 

  System.MarshalByRefObject

    System.ComponentModel.Component

      System.Windows.Forms.Control

對於iOS裡的UI類,也有類似的繼承關係。

例如對於UITextField,繼承於UIControl;UIControl繼承於UIView,UIView繼承於UIResponder,UIResponder繼承於NSObject。

具體架構可以參見:

http://developer.apple.com/library/ios/#documentation/general/conceptual/Devpedia-CocoaApp/Responder.html

 

 

UIResponder是UIKit架構中的類(Mac OS X Cocoa對應的是AppKit架構)。

 

2. 第一響應對象

在應用的響應對象裡,會有一個成為第一響應對象。

第一響應對象和其他響應對象之間有什麼區別?對於普通的觸摸事件沒什麼區別。就算我把一個按鈕設定成第一響應對象,當我點擊其他按鈕時,還是會響應其他按鈕,而不會優先響應第一響應對象。

第一響應對象的區別在於負責處理那些和螢幕位置無關的事件,例如搖動。

蘋果官方文檔的說法是:第一響應對象是視窗中,應用程式認為最適合處理事件的對象。

一個班只能有一個班長,應用的響應對象中,只能有一個響應對象成為第一響應對象。

 

3. 成為與取消第一響應對象。

要當第一響應對象,還需要有View來毛遂自薦:

- (BOOL) canBecomeFirstResponder{    returnYES;}

 

如果缺少了這段,就算用[view becomeFirstResponder]也不能讓一個view成為第一響應對象。。。強扭的瓜不甜?好吧不是這個原因。大多數視圖預設只關心與自己有關聯的事件,並且(幾乎)總是有機會來處理這些事件。以UIButton為例,當使用者單擊某個UIButton對象時,無論當前的第一響應對象是哪個視圖,該對象都會收到指定的動作訊息。當上第一響應對象吃力不討好麼。。。所以只能由某個UIResponder明確表示自己願意成為第一響應對象才行。(我不知道設計上是基於什麼考慮。。。安全?)

 

在當上第一響應對象時,不同對象可能會有一些特殊的表現。例如UITextField當上的時候,就會調出一塊小鍵盤。

第一響應對象也有可能被辭退。發送一個resignFirstResponder,就可以勸退。

 

4. 第一響應對象的任務

剛才說了第一響應對象可以處理搖動。就來看個範例吧:

 

- (void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{    if(motion == UIEventSubtypeMotionShake)    {        NSLog(@"Device is beginning to shake");        [selfsetCircleColor:[UIColorredColor]];        [selfsetNeedsDisplay];    }}

 

當搖動開始時觸發某些行為。

 

5. 擷取當前第一響應對象

源自這篇討論:http://stackoverflow.com/questions/1823317/get-the-current-first-responder-without-using-a-private-api 

提問的傢伙用了如下的方式來擷取

UIView   *firstResponder = [keyWindow performSelector:@selector(firstResponder)];

結果被蘋果打回來,說用了非公開的API。。。

於是這傢伙只好苦逼地用遞迴了:

implementationUIView (FindFirstResponder)- (UIView *)findFirstResponder{    if (self.isFirstResponder) {                return self;         }    for (UIView *subView in self.subviews) {        UIView *firstResponder = [subView findFirstResponder];        if (firstResponder != nil) {            return firstResponder;        }    }    return nil;} @end

 

恩。。。所以如果有必要的話,要麼指定一個固定的第一響應對象,要麼弄個全域變數來儲存當前第一響應對象?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.