標籤:
在開發應用的過程中,我們需要頻繁地在介面之間傳遞訊息,有時候是傳遞資訊,有時候是傳遞一個訊號即可。在iOS開發中,有多種傳遞資訊的方式。比如最簡單的,如果我們要在從一個介面進入另一個介面時給新介面傳遞一些訊息,只需要給新介面定義一些屬性,然後在建立新介面的時候設定其屬性值即可。
那麼如果要從新介面反過來傳遞資訊給原先的介面怎麼做呢,怎麼建立起一個溝通的橋樑呢?iOS也提供了很多種方式,比如Notification、Block、UserDefault等等。本文就講解最常見也是最常用的一種方式,幾乎每個學習了一段iOS開發的人都見過也用過,只是可能不明白,那就是Delegate——委託。
回想一下,在使用列表,也就是UITableView的時候,除了建立這個列表對象,還會用到UITableView Datasource和UITableView Delegate。當我們要設定點擊列表行的相應時,就要用到UITableView Delegate的方法,這裡要講的,跟這個是同一個東西。
先看一個效果:
在主介面有一個按鈕和一個方塊,方塊原本是隱藏的。進入子介面,子介面有兩個按鈕,一個用來告訴主介面顯示方塊,一個用來告訴主介面隱藏方塊。那子介面時怎麼告訴主介面的呢?
抽象地說,delegate就是一個協議。這個協議由子介面定下規矩,比如點擊顯示方塊的按鈕會如何,點擊隱藏的按鈕又會如何。任何介面都可以聲明我要遵循子介面的這個協議。然後當在子介面觸發協議內容,也就是這裡的點擊兩個按鈕時,遵循協議的介面,這裡就是主介面,就會收到一個訊號,然後進行相應的操作即可。這個訊號可以包含一些資訊,比如各種對象:字串、圖片、資料流等等,也可以不包含資訊,僅僅是一個訊號。這個例子中就僅僅是不包含資訊的訊號,比如要顯示方塊的訊號和要隱藏方塊的訊號。
來看看代碼:
先看子介面,我們說子介面要定下規矩,首先要在.h檔案中聲明規矩:
@protocol SecondViewControllerDelegate- (void)showTheSquare;// 顯示方塊的委託- (void)dismissTheSquare;// 隱藏方塊的委託@end@interface SecondViewController : UIViewController@property (nonatomic, weak) id<SecondViewControllerDelegate> delegate;// 聲明delegate對象@end
可以看到,子介面首先定義了兩個協議,一個表示顯示方塊,一個表示隱藏方塊,其本質是兩個方法。然後聲明了一個屬性,同聲明其他對象一樣,只不過這裡是一個delegate對象,其類型為我們上面聲明的協議類型。
定下規矩名後,我們要在點擊按鈕的時候去使用規矩,所以在.m檔案中:
// 顯示方塊- (void)showSquare { [self.delegate showTheSquare];// 調用委託方法 [self.navigationController popViewControllerAnimated:YES];// 返回上個介面}// 隱藏方塊- (void)dismissSquare { [self.delegate dismissTheSquare];// 調用委託方法 [self.navigationController popViewControllerAnimated:YES];// 返回上個介面}
在兩個按鈕的回應程式法中,分別用delegate對象調用了定下的兩個委託方法。這樣子介面的工作就做完了。
回到主介面,我們之前說,主介面要表示我遵循子介面定下的規矩,怎麼聲明呢?和使用UITableView對象時的做法一樣,在.m檔案的開頭表示一下就好:
// 遵循子介面的協議@interface ViewController ()<SecondViewControllerDelegate>
這裡的協議名就是我們在子介面中聲明協議時定下的名字,還記得吧,這個協議中我們定下了兩個方法,分別表示顯示和隱藏方塊。另外要特別注意不能忘記的是,在建立子介面的時候,要將子介面的屬性——delegate對象,設為self:
// 進入子介面- (void)showSecondView { SecondViewController *secondVC = [[SecondViewController alloc] init]; secondVC.delegate = self; [self.navigationController pushViewController:secondVC animated:YES];}
這其實就跟我們用UITableView時要把tableView的delegate和datasource都設為self是一個道理,這樣才能收到訊息。
好了。我們之前已經在子介面中設定了,點擊兩個按鈕會調用那兩個方法,但是這兩個方法具體要做什麼,確實在主介面中設定的。因為任何介面都可以遵循使用這些協議方法,而每個介面的需求是不一樣的,子介面只負責喊話說我要調用這個方法了,具體方法幹什麼還是在主介面中實現,這裡我們就是顯示和隱藏方塊:
#pragma mark - SecondViewController Delegate// 顯示方塊- (void)showTheSquare { self.square.alpha = 1;}// 隱藏方塊- (void)dismissTheSquare { self.square.alpha = 0;}
這樣就可以實現上面動圖的效果了,也就是說,子介面成功地把訊號傳遞迴了主介面,稱為回調。如果你在自己的開發中發現沒有效果,最可能的就是忘記將delegate屬性設為self了,這樣是收不到訊號的。
我們最開始也說了,有時候只需要傳遞訊號,而有時候需要傳遞一些具體的資訊對象,那要怎麼做呢?其實也很簡單,我們的協議不是規定了很多方法嗎,在這些方法裡加上參數就可以把資料對象當參數傳遞了~
查看樣本工程:https://github.com/Cloudox/DelegateDemo
著作權:http://blog.csdn.net/cloudox_
iOS頁面間傳遞訊息之Delegate