剛開始作iOS開發的時候,對 protocol、delegate 的理解一直都是暈暈乎乎只知其一;不知其二的狀態,不知道兩個UIViewController之間怎麼進行傳值。ios
面試過幾個童鞋,問道怎麼用 delegate 對 兩個 UIViewController 進行傳值的時候,回答的都是模棱兩可的。今天又有童鞋問我這個問題,因此乾脆寫個blog說明一下。面試
一、協議(protocol),就是使用了這個協議後,必須按照協議規定的內容來處理事情,協議中要求的方法必須實現(@optional的方法除外)。設計模式
protocol是一種語法,它提供了一個很方便的、實現delegate模式的機會。單元測試
定義protocol以下:學習
@protocol ClassBDelegate<NSObject> - (void)methodOne;
@optional - (void)methodTwo:(NSString *)value; @end
定義了一個ClassB的協議,這個協議中包含兩個方法,其中methodTwo爲可選的。測試
在ClassA的頭文件(ClassA.h)中實現這個協議,以下代碼:atom
@interface ClassA<ClassBDelegate> @end
在ClassA的實現文件(ClassA.m)中實現ClassBDelegate的兩個方法,其中methodTwo能夠不實現,以下:spa
- (void)methodOne{ // 具體實現內容 } - (void)methodTwo:(NSString *)value{ // 具體實現內容 }
二、代理(delegate),顧名思義就是委託別人辦事,當一件事情發生後,本身不處理,讓別人來處理。設計
delegate和protocol沒有關係。delegate自己是一種設計模式。是把一個類本身須要作的一部分事情,讓另外一個類(也能夠就是本身自己)來完成。3d
在ClassB的頭文件(ClassB.h)中定義一個代理以下:
@interface ClassB @property (nonatomic, unsafe_unretained) id<ClassBDelegate> delegate; @end
這樣,當咱們在ClassB的實現文件(ClassB.m)中遇到想讓別的類(如 ClassA)處理的問題時,就能夠這樣
[self.delegate methodOne]; [self.delegate methodTwo:@"須要傳遞的值"];
三、上邊簡單的介紹了一下協議與代理,如今開始講兩個UIViewController之間怎麼進行傳值的事例。
首先啓動Xcode,從菜單選擇file-New Project...,彈出以下窗口:
選擇Single View Application,而後點擊 Next,彈出以下窗口:
a、給工程取個名稱爲 DelegateByValue;
b、下邊的組織名稱寫本身所在的組織,這裏寫的是我我的的名稱;
c、公司標識分爲兩部分,com也就是Company(公司)的意思,iostour寫本身所在的公司名稱,這裏我寫的是iOS之旅的iostour;
d、類前綴,這個能夠隨便,不過我這裏寫的是W,由於我姓衛,因此取其首字母,這樣公司同事一看到這個類就知道是我寫的;
e、設備選擇iPhone;
f、咱們用xib的方式編寫,故此處不勾選;
g、使用ARC機制,勾選;
h、該事例不作單元測試,不勾選。
而後單擊 Next,彈出以下窗口:
選擇一個存儲工程的目錄,而後單擊 Create建立一個工程,建立完成後的目錄結構以下:
接下來咱們須要在兩個Controller之間進行傳值,因爲建立工程的時候已經自動爲咱們生成了一個WViewController,因此咱們只須要在建立一個就Controller就好啦。
鼠標右鍵DelegateByValue,點擊New File... 以下:
而後彈出以下窗口
選擇iOS>Cocoa Touch >Objective-C Class,而後單擊 Next,彈出以下窗口:
而後,取名爲WTwoViewController,單擊 Next,選擇存儲目錄,而後Create。
接下來爲WTowViewController 建立一個.xib文件,步驟以此以下:
a、鼠標右鍵DelegateByValue,點擊New File...
b、而後彈出以下窗口:
此次咱們選擇iOS > User Interface > View,單擊 Next,取名爲WTwoViewController,而後Create。
建立好WTwoViewController後,咱們讓WTwoViewController.xib與WTwoViewController.h關聯起來,以下圖:
按照上圖一、二、3的步驟依次進行,選中1,點擊2,設置3 Class爲WTwoViewController,而後回車,而後以下圖:
點擊四、按住5 view後邊的空心圓,拖動到6 view上,而後鬆手及
接下來給view上拖一個UITextField和一個UIButton,並給UITextField起名爲txtValue,給UIButton設置一個Action,起名爲pressChange
步驟以下:
一、分屏顯示xib與代碼,
二、選擇UITextField,並按住control鍵, 拖動到右側的代碼(WTwoViewController.h)區域,會彈出以下窗口:
爲其設置名稱,而後點擊Connect;
三、一樣,選擇UIButton,並按住control鍵,拖動到右側代碼(WTwoViewController.h)區域,會彈出以下窗口:
此次由於是要給UIButton設置點擊事件,因此改變1 Connection爲Action,而後設置名稱,點擊Connect。
至此WTwoViewController的窗口視圖以設置完成。
一樣步驟設置WViewController.xib窗口。
給 view 上拖一個UILabel和一個UIButton,並給UILabel起名爲lblValue,給UIButton設置一個Action,起名爲pressCasting。
至此窗口設置部分已經所有完成,效果以下:
接下來在WTwoViewController.h中定義一個協議,WTwoViewControllerDelegate,並給WTwoViewController定義一個代理,代碼以下:
// // WTwoViewController.h // DelegateByValue // // Created by wzrong on 13-7-20. // Copyright (c) 2013年 wzrong. All rights reserved. // #import <UIKit/UIKit.h> /** 定義協議,用來實現傳值代理 */ @protocol WTwoViewControllerDelegate <NSObject> /** 此方爲必須實現的協議方法,用來傳值 */ - (void)changeValue:(NSString *)value; @end /** 彈出來的Controller,須要從這個頁面回傳值到調用它的WViewController中 */ @interface WTwoViewController : UIViewController /** 此處利用協議來定義代理 */ @property (nonatomic, unsafe_unretained) id<WTwoViewControllerDelegate> delegate; /** 這個文本框中的值能夠本身隨意改變。 當點擊「我變變變!」按鈕後,它裏邊的值會回傳到調用它的WViewController中 */ @property (nonatomic, strong) IBOutlet UITextField *txtValue; /** 「我變變變!」 按鈕點擊事件,用來處理按鈕點擊後的事情。 此例中用來發送代理,並退出當前窗體 */ - (IBAction)pressChange:(id)sender; @end
接下來在WTwoViewController.m中的 - (IBAction)pressChange:(id)sender 方法中把代理派發出去,順便把窗口給銷燬,代碼以下:
/** 「我變變變!」 按鈕點擊事件,用來處理按鈕點擊後的事情。 此例中用來發送代理,並退出當前窗體 */ - (IBAction)pressChange:(id)sender { // 發送代理,並把文本框中的值傳過去 [self.delegate changeValue:self.txtValue.text]; // 退出當前窗口 [self dismissViewControllerAnimated:YES completion:nil]; }
WTwoViewController中的設置已經完成,接下要在WViewController中調用WTwoViewController,並實現WTwoViewControllerDelegate代碼。
首先在WViewController.h中實現代理,代碼以下:
// // WViewController.h // DelegateByValue // // Created by wzrong on 13-7-20. // Copyright (c) 2013年 wzrong. All rights reserved. // #import <UIKit/UIKit.h> #import "WTwoViewController.h" /** 主 Controller,經過此 Controller 調用 WTwoViewController,而後把 WTwoViewController 傳遞過來的值賦給 UILabel 此 Controller 實現了 WTwoViewControllerDelegate 這個協議 */ @interface WViewController : UIViewController<WTwoViewControllerDelegate> /** 用來顯示 Delegate 傳過來的值 */ @property (strong, nonatomic) IBOutlet UILabel *lblValue; /** 「施法」按鈕事件,用來處理點擊「施法」按鈕後的事情。 此事例中要來調用彈出 WTwoViewController */ - (IBAction)pressCasting:(id)sender; @end
其在WViewController.m的 - (IBAction)pressCasting:(id)sender 方法中調用WTwoViewController,並設置代理的回調方法,代碼以下:
/** 「施法」按鈕事件,用來處理點擊「施法」按鈕後的事情。 此事例中要來調用彈出 WTwoViewController */ - (IBAction)pressCasting:(id)sender { // 給 WTwoViewController 非配內存,並初始化xib文件 WTwoViewController *controller = [[WTwoViewController alloc]initWithNibName:@"WTwoViewController" bundle:nil]; // 設置代理到此Controller controller.delegate = self; // 彈出 WTwoViewController [self presentViewController:controller animated:YES completion:nil]; } /** 此方爲必須實現的協議方法,用來傳值 */ - (void)changeValue:(NSString *)value{ // 改變UILabel的值 self.lblValue.text = value; }
OK,搞定。
這裏只實現了從WTwoViewController到WViewController的傳值,你們能夠本身作作從WViewController到WTwoViewController的傳值。
工程源碼傳送門DelegateByValue
著做權聲明:本文由 http://wzrong.cnblogs.com 或者 http://iostour.diandian.com 原創,歡迎轉載分享。 請尊重做者勞動,轉載時保留該聲明和做者博客連接,謝謝!
原創文章,如需轉載請註明出處,謝謝!
歡迎訪問本人技術微博 @iOS之旅 相互交流,共同窗習,共同進步!
歡迎訪問本人微博 @衛志榮