之前介绍过代码块反向传值,现在再整理一个常用的代理传值(委托传值);
这样就不得不提到iOS中的协议,代理传值是在协议的基础上实现的;所谓的协议,简单地说就是一个声明一些方法的头文件,方法不需要自己实现,需要遵循协议的类来实现;协议可以寄生在一个其它类的头文件里面也可以自己单独拥有一个头文件,这里我们寄生在其它类的头文件里面,这样实现代理传值也比较的方便直观。
直接通过代码来介绍了:
我们先来建两个类,根视图MainViewController(同时也是遵循协议并实现协议方法的类)和SubViewController(即协议声明寄生的类,也是需要给MainViewController反向传值的类)。
在SubViewController.h中声明一个协议,以及一个遵循协议的属性,如下代码:
#import <UIKit/UIKit.h>
//这部分是添加的协议
@protocol ceShiXieYi <NSObject>
@optional
-(void)sendMessage:(NSString *)aString;
@end
@interface SubViewController : UIViewController
//本类中声明的遵循协议的属性adelegate
@property (weak,nonatomic) id<ceShiXieYi>adelegate;
@end
注意:
1.协议部分中的protocol是协议声明的关键字,optional是声明方法的类型,意思是可实现可不实现,如果换成required则说明方法是必须实现的。
2.本类声明的遵循协议的属性adelegate的特性用的是weak,因为本项目用的是ARC,如果是非ARC可以选择assign;不要去用retain和strong,这样做是为了避免循环引用造成内存泄露。
这样可以在SubViewController.m的任意部分通过属性adelegate来调用方法-(void)sendMessage:(NSString *)aString;(因为方法的实现在MainViewController.m中,所以可以完成在SubViewController中调用方法时把一些数值作为参数传到MainViewController中或者改变MainViewController的页面布局)
这里简单的在SubViewController.m中添加一个按钮来通过adelegate调用-(void)sendMessage:(NSString *)aString实现传值,代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIButton *myButton=[UIButton buttonWithType:UIButtonTypeCustom];
[myButton setTitle:@"返回" forState:UIControlStateNormal];
[myButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
myButton.frame=CGRectMake(100, 400, 100, 50);
[myButton addTarget:self action:@selector(myButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myButton];
}
-(void)myButtonAction
{
[self.adelegate sendMessage:@"路飞"];//调用协议中的方法,并实现传值
[self.navigationController popViewControllerAnimated:YES];
}
在MainViewController.m中导入SubViewController.h,并让MainViewController遵循SubViewController.h声明的协议,代码如下:
#import "MainViewController.h"
#import "SubViewController.h"
@interface MainViewController ()<ceShiXieYi>
@end
然后在MainViewController.m实例化SubViewController的一个对象,给这个对象的属性adelegate赋值,并实现协议里面声明的方法,代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIButton *myButton=[UIButton buttonWithType:UIButtonTypeCustom];
[myButton setTitle:@"下一页" forState:UIControlStateNormal];
[myButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
myButton.frame=CGRectMake(100, 400, 100, 50);
[myButton addTarget:self action:@selector(myButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myButton];
}
-(void)myButtonAction
{
SubViewController *subV=[[SubViewController alloc]init];
subV.adelegate=(id)self;//让SubViewController中的属性adelegate成为本类的对象
[self.navigationController pushViewController:subV animated:YES];
}
//实现协议中的方法
-(void)sendMessage:(NSString *)aString
{
NSLog(@"胜利者是:%@",aString);
}
这样就实现了通过代理方法实现反向传值了,最终打印结果:
[4897:193466]胜利者是:路飞