看板 Knuckles_note
作者 Knuckles (站長 那克斯)
標題 [Xcode] 建立類別的 protocol 使用 delegate 函數
時間 2014年10月05日 Sun. PM 11:41:42
當有需要在類別中,建立一組讓另一個類別可以執行的成員函數
要使用 protocol 宣告 delegate 函數
例如在 Master-Detail 的架構下,有兩個頁面:
MasterViewController 與 DetailViewController
Master 裡有個成員變數 _name ,會用個 Label 顯示使用者名稱
點一下會連進 Detail,並將 _name 的值傳給 Detail
在 Detail 裡有 Text 可以修改使用者名稱
當在 Detail 裡修改了使用者名稱後,回到 Master 卻發現使用者名稱沒有變
要如何在 Detail 裡修改名稱後,通知 Master 將使用者名稱也變新的呢?
在 Objective-C 裡是用一個特別的 delegate 函數來處理這問題
delegate 就是委任的意思,因為 Detail 沒有辦法改 Master 裡的成員變數 _name
所以產生一個 delegate 函數,將這函數的實作放在 Master 裡
當 Detail 需要的時候可以呼叫並傳值給放在 Master 裡的 delegate 函數
而 Detail 的 delegate 函數因為放在 Master 裡,所以可以存取 Master 的成員變數
實際的作法為:
先在
DetailViewController.h 用 @protocal 宣告 delegate 函數
在 @interface DetailViewController : UIViewController 的上一行加上
@protocol DetailViewControllerDelegate <NSObject>
- (void)didChangeName:(NSString *)name;
@end
在 @interface DetailViewController : UIViewController 的下一行加上
@property (nonatomic, weak) id <DetailViewControllerDelegate> delegate;
這邊我們在 DetailViewController 類別裡新增了一個成員變數 delegate
且宣告了一個 delegate 函數 -didChangeName:
修改
DetailViewController.m
當在 DetailViewController 的某個成員函數中修改了使用者名稱後,執行
[self.delegate didChangeName:name]
將修改後的 name 傳給這個 delegate 函數
而這個 delegate 函數的實作是寫在 MasterViewController
所以可以修改 MasterViewController 的成員變數
修改
MasterViewController.h
加上
#import "DetailViewController.h"
在 @interface MasterViewController : UITableViewController
這行尾端加上
<DetailViewControllerDelegate>
修改
MasterViewController.m
加上可以讓 DetailViewController 呼叫的 delegate 函數
- (void)didChangeName:name{
//修改 MasterViewController 的成員變數 _name
_name = name;
[self.tableView reloadData];
}
在 storyboard 中,設定連結 MasterView 與 DetailView 的 segue
將 identifier 改為 ChangeName
然後修改 MasterViewController.m 的 -prepareForSegue:sender: 為
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"ChangeName"]) {
DetailViewController *detailViewController = segue.destinationViewController;
detailViewController.delegate = self;
}
}
就是在用 segue 切換頁面時
將 MasterViewController 的指標存在 DetailViewController 裡的成員變數 delegate
這樣 DetailViewController 就可以用 [self.delegate didChangeName:name]
呼叫放在 MasterViewController 的 delegate 函數了
--
--
※ 作者: Knuckles 時間: 2014-10-05 23:41:42
※ 編輯: Knuckles 時間: 2015-03-12 14:53:57