iOS 開發之協議-代理傳值


剛開始做iOS開發的時候,對 protocol、delegate 的理解一直都是暈暈乎乎一知半解的狀態,不知道兩個UIViewController之間怎么進行傳值。

面試過幾個童鞋,問道怎么用 delegate 對 兩個 UIViewController 進行傳值的時候,回答的都是模棱兩可的。今天又有童鞋問我這個問題,所以干脆寫個blog說明一下。

1、協議(protocol),就是使用了這個協議后,必須按照協議規定的內容來處理事情,協議中要求的方法必須實現(@optional的方法除外)。

protocol是一種語法,它提供了一個很方便的、實現delegate模式的機會。

定義protocol如下:

@protocol ClassBDelegate<NSObject>

- (void)methodOne;
@optional
- (void)methodTwo:(NSString *)value; @end

 

定義了一個ClassB的協議,這個協議中包含兩個方法,其中methodTwo為可選的。

在ClassA的頭文件(ClassA.h)中實現這個協議,如下代碼:

@interface ClassA<ClassBDelegate>

@end

 

在ClassA的實現文件(ClassA.m)中實現ClassBDelegate的兩個方法,其中methodTwo可以不實現,如下:

- (void)methodOne{
    // 具體實現內容
    
}

- (void)methodTwo:(NSString *)value{ 
    // 具體實現內容  
}

 

2、代理(delegate),顧名思義就是委托別人辦事,當一件事情發生后,自己不處理,讓別人來處理。

delegate和protocol沒有關系。delegate本身是一種設計模式。是把一個類自己需要做的一部分事情,讓另一個類(也可以就是自己本身)來完成。

在ClassB的頭文件(ClassB.h)中定義一個代理如下:

@interface ClassB

@property (nonatomic, unsafe_unretained) id<ClassBDelegate> delegate;

@end

 

這樣,當我們在ClassB的實現文件(ClassB.m)中遇到想讓別的類(如 ClassA)處理的問題時,就可以這樣

[self.delegate methodOne];

[self.delegate methodTwo:@"需要傳遞的值"];

3、上邊簡單的介紹了一下協議與代理,現在開始講兩個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關聯起來,如下圖:

  按照上圖1、2、3的步驟依次進行,選中1,點擊2,設置3 Class為WTwoViewController,然后回車,然后如下圖:

點擊4、按住5 view后邊的空心圓,拖動到6 view上,然后松手及

接下來給view上拖一個UITextField和一個UIButton,並給UITextField起名為txtValue,給UIButton設置一個Action,起名為pressChange

步驟如下:

1、分屏顯示xib與代碼,

2、選擇UITextField,並按住control鍵, 拖動到右側的代碼(WTwoViewController.h)區域,會彈出如下窗口:

為其設置名稱,然后點擊Connect;

3、同樣,選擇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之旅 相互交流,共同學習,共同進步!

歡迎訪問本人微博 @衛志榮

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM