在平常的iOS开发中,传值问题是十分普遍的,上次已经介绍过一种传值的方法了,这种方法传值实现顺传比较方便但并不适合逆传,即从B页面将值传回A页面,详情请看iOS属性传值,这里我要介绍的是一种常用的逆传方法:代理传值。
·代理传值
- 首先创建两个控制器A、B,这里不再进行赘述
- 接着来到B控制器的.h文件中–直接上代码:
/*
功能要求:从BController通过delegate传值到AController,并显示出来
AController:遵守协议,设置代理,实现协议方法
BController:制定协议,申明协议方法
注意:代理不能写在viewDidLoad里面
*/
#import <UIKit/UIKit.h>
@class BController;
// 定义协议
@protocol BControllerDelegate <NSObject>
//用required修饰的方法是必须实现的.协议默认声明在其中的方法为必须实现的方法.
//用optional修饰的方法可以不实现. 在用到的时候需要先判断方法是否存在(若没有用到而你没有进行判断方法是否存在则会报方法找不到的错误)
@optional
// 定义要执行方法
//- (void)passValuesToFirstVC:(NSString *) values;
- (void)viewController:(BController *)viewController didPassValuesWithInfo:(NSString *)info;
@end
@interface BController : UIViewController
/*
delegate的属性使用:
1.为了防止死循环,delegate不能使用strong/retain等关键字修饰
2.MRC下使用assign修饰
3.ARC下使用weak修饰
*/
@property (nonatomic, weak) id<BControllerDelegate> delegate;//要成为代理必须遵守协议
@end
- 来到B控制器的.m文件中–直接上代码:
#import "BController.h"
@interface BController ()<UITextFieldDelegate>
@property (nonatomic, strong) UITextField *textField;
@end
@implementation SecondViewController
// 重写get方法
-(UITextField *)textField
{
if (_textField == nil) {
_textField = [[UITextField alloc] initWithFrame:CGRectMake(75, 100, 200, 50)];
_textField.layer.borderWidth = 2;
_textField.layer.borderColor = [UIColor cyanColor].CGColor;
_textField.layer.cornerRadius = 10;
}
return _textField;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.textField];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFastForward target:self action:@selector(backBeforeVC)];
// 设置此控制器为键盘回收代理
_textField.delegate = self;
}
// 点击控制器的view,键盘回收
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.textField resignFirstResponder];
}
// 点击返回按钮执行事件
- (void)backBeforeVC
{
// 判断代理方法是否存在
if ([_delegate respondsToSelector:@selector(viewController:didPassValuesWithInfo:)])
{
// 执行代理方法
[_delegate viewController:self didPassValuesWithInfo:self.textField.text];
}
// 跳转控制器
[self.navigationController popViewControllerAnimated:YES];
}
@end
- 来到Controller的.m文件–直接上代码:
#import "AController.h"
#import "BController.h"
@interface FirstViewController ()<AControllerDelegate>//遵守A控制器协议
@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) Controller *Bvc;
@end
@implementation AController
// 重写label的get方法
-(UILabel *)label
{
if (_label == nil) {
_label = [[UILabel alloc] initWithFrame:CGRectMake(75, 100, 200, 50)];
_label.layer.borderColor = [UIColor yellowColor].CGColor;
_label.layer.borderWidth = 2;
_label.layer.cornerRadius = 10;
}
return _label;
}
// 实现代理方法
-(void)viewController:(BController *)viewController didPassValuesWithInfo:(NSString *)info
{
// 传值
self.label.text = info;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.label];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"点击进入" style:UIBarButtonItemStylePlain target:self action:@selector(enterNextVC)];
}
// 懒加载,初始化Bvc
-(BController *)Bvc
{
if (_secondVC == nil) {
_Bvc = [[BController alloc] init];
}
return _Bvc;
}
// 点击跳转下一界面的方法
- (void)enterNextVC
{
[self.navigationController pushViewController:self.secondVC animated:YES];
_Bvc.delegate = self;//告诉当前控制器要成为B控制器代理
}
@end