iOS 开发之协议-代理传值

刚开始作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之旅 相互交流,共同窗习,共同进步!

欢迎访问本人微博 @卫志荣

相关文章
相关标签/搜索