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

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

iOS 开发之协议-代理传值的更多相关文章

  1. iOS开发总结——协议代理的认识

    1.前言 自今年5月底正式转iOS之后,天天get新技能,很多技能在脑子里回旋不吐不快,所以,写点东西整理一下.先从协议代理开始. 2.协议方法的声明 @protocol EventMenuBarDe ...

  2. iOS开发 中的代理实现

    iOS开发 中的代理实现 关于今天为什么要发这篇文字的原因:今天在和同事聊天的时候他跟我说项目中给他的block有时候不太能看的懂,让我尽量用代理写,好吧心累了,那就先从写个代理demo,防止以后他看 ...

  3. 【转】iOS 开发之协议protocal-代理传值delegate

    原文网址:http://www.cnblogs.com/wzrong/p/3201938.html 刚开始做iOS开发的时候,对 protocol.delegate 的理解一直都是晕晕乎乎一知半解的状 ...

  4. 浅谈iOS开发的协议(protocol)和代理(delegate)

    协议和代理对于一个新手来说确实不讨好理解,也有很多的iOS开发的老手对此是懂非懂的.网上的很多博文只是讲了怎么使用,并没有说的很明白.下面我谈一下我的理解. 1.你要先搞明白,协议和代理为什么会出现, ...

  5. Ios开发之协议protocol

    Protocol是ios开发中的一个难点也是一个重点,要想使用好,或者理解好它,可能需要时间的累积.今天我们就通过一个例子来简单的看一下,怎么样使用protocol. 我们今天用的例子就是模拟电脑插入 ...

  6. iOS开发 - Protocol协议及委托代理(Delegate)

    因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来代替.Protocol(协议)只能定义公用的一套接口,但不能提供具体的实现方法.也就是说,它只告诉你要做什么,但具体怎 ...

  7. iOS开发HTTP协议相关知识总结

    HTTP原理 什么是URL URL中常见的几种协议 什么是HTTP协议 HTTP是做什么的 为什么要使用HTTP协议 HTPP协议的通信过程介绍 HTTP请求 HTTP响应 HTTP请求的选择 两种发 ...

  8. iOS开发之地图代理不起作用(提示vImage decode failed, falling back to CG path.)

    项目中用到了地图相关的东西,就把曾经的demo搬了出来,结果发现直接执行之前的demo没有问题,在xcode5下新建项目再把代码粘贴过来就会提示 May 5 11:36:21 infomedia-iP ...

  9. IOS开发之----协议与委托(Protocol and Delegate) 实例解析

    1 协议: 协议,类似于Java或C#语言中的接口,它限制了实现类必须拥有哪些方法. 它是对对象行为的定义,也是对功能的规范. 在写示例之前我给大家说下@required和@optional这两个关键 ...

随机推荐

  1. 内存排查 valgrind

    内存问题排查工具 --- valgrind 1. 概述 2. Valgrind 3. 内存泄漏监测 3.1. 示例代码 3.2. 编译它 3.3. 用Valgrind监测进程的内存泄漏 4. 悬挂指针 ...

  2. iOS_文章3党库SDWebImage

    1,下载的文章3党库SDWebImage代码包增加到project 2,进入project的Build Phases,将源代码包里面的所有.m文件所有加入到project 3,导入第3方类库依赖的两个 ...

  3. sql server 视图 的一个例子

    这是一个 有点复杂的查询.我现在 想把他封装 成 视图  其中  B.RecordID= 41 提供给 视图外查询. create view view_UserRecord as select Rec ...

  4. HDU 4052 Adding New Machine(矩形面积并)

    Adding New Machine Problem Description Incredible Crazily Progressing Company (ICPC) suffered a lot ...

  5. c# 自定义数据类型

    定义引用类型用 class  ,值类型 用 struct ,涉及数据转换就用 上一篇的方法做 ,涉及 泛型就用 in  关键字 不用 in interface IContravariant<A& ...

  6. PL/SQL联系oracle成功可以sql解决的办法是检查表的名称无法显示

    有时,因为机器突然断电或其他原因PL/SQL它甚至不能在数据库表后显示.序列和其它元素.使用SQL Windows运行查询一般查询,登录或同样的现象再次. 我是不是可以解决因重复登录的猜测是,PLSQ ...

  7. [Cocoa]深入浅出 Cocoa 之消息

    深入浅出 Cocoa 之消息    罗朝辉(http://blog.csdn.net/kesalin) 转载请注明出处 在入门级别的ObjC 教程中,我们常对从C++或Java 或其它面向对象语言转过 ...

  8. 在asp.net webservice中如何使用session

    原文:在asp.net webservice中如何使用session 原文:刘武|在asp.net webservice中如何使用session 在使用asp.net编写webservice时,默认情 ...

  9. STL源代码分析——STL算法sort排序算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...

  10. 安卓WindowManager注入事件如何跳出进程间安全限制

    在分析monkey源码的时候有些背景知识没有搞清楚,比如在看到monkey是使用windowmanager的injectKeyEvent方法注入事件的时候,心里就打了个疙瘩,这种方式不是只能在当前应用 ...