iOS中传值方式有好几种,分别是:代理传值,block传值,属性传值,通知传值,单例传值,利用userdefault或者文件方式传值,通常代理传值和block传值使用最普遍,本文介绍代理传值的方式,后续博客会一次写上其他传值方式。
一 什么是委托代理?
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:@"需要传递的值"];
二 具体实例
实现的功能是:在viewcontroller中创建一个UIButton按钮用于push到下一个页面,和一个UILable用于显示从第二个页面传回的文字,在secondviewcontroller中创建一个UITextfield用于输入文字。在输入完成按下back返回第一个页面后,在lable上显示输入的文字。
1 工程截图
2 ViewController.h文件
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
3 ViewController.m文件
#import "ViewController.h"
#import "SecondViewController.h"
@interface ViewController ()<getTextFromDelegate>
{
UIButton *_button;
UILabel *_lable;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initLayout];
}
- (void)initLayout{
_button = [UIButton buttonWithType:UIButtonTypeSystem];
_button.frame = CGRectMake(0, 0, 100, 50);
_button.center = self.view.center;
_button.backgroundColor = [UIColor redColor];
[_button addTarget:self action:@selector(pushToNextViewController:) forControlEvents:UIControlEventTouchUpInside];
[_button setTitle:@"下一页" forState:UIControlStateNormal];
[self.view addSubview:_button];
_lable = [[UILabel alloc]initWithFrame:CGRectMake(10, 64, 355, 200)];
_lable.backgroundColor = [UIColor orangeColor];
[self.view addSubview:_lable];
}
- (void)pushToNextViewController:(UIButton *)sender{
SecondViewController *secondVC = [SecondViewController new];
//代理就是本身
secondVC.delegate = self;
[self.navigationController pushViewController:secondVC animated:YES];
}
#pragma mark 实现代理方法
- (void)getText:(NSString *)text{
_lable.text = text;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
4 SecondViewController.h文件
#import <UIKit/UIKit.h>
@protocol getTextFromDelegate <NSObject>
//声明协议方法
- (void)getText:(NSString *)text;
@end
@interface SecondViewController : UIViewController
@property (weak, nonatomic)id<getTextFromDelegate>delegate;
@end
4 SecondViewController.m文件
#import "SecondViewController.h"
@interface SecondViewController ()<getTextFromDelegate>
{
UITextField *_textField;
}
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
_textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];
_textField.backgroundColor = [UIColor redColor];
_textField.center = self.view.center;
[self.view addSubview:_textField];
}
#pragma mark 在页面将要消失时
- (void)viewWillDisappear:(BOOL)animated{
//将本页面获取的值传递给上一个页面去实现
[self.delegate getText:_textField.text];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
三 模拟器运行结果截图