在做项目的时候,传值是经常遇到到了,而传值的方法也是多样的,其中,协议/代理就是一种常常用到的传值方式.
什么情况用协议?
第一个类里创建了第二个类的对象,并给第二个类传值
当第二个类的对象想控制第一个类里的方法或给第一个类传值,必须用协议
下面就用代码简单描述一下:
我创建了一个RootViewController,并把RootViewController的视图封装到了一个继承UIView的类里,起名叫RootView.
还创建了一个二级页面,起名叫FirstViewController
当我在RootView里写了个Button,并且点击Button想要跳转到FirstViewController的时候,就要用到协议,因为UIView是不能执行跳转事件,只能将点击事件传到父视图,由父视图进行跳转.
RootView.h
#import <UIKit/UIKit.h>
// 1 声明协议
@protocol RootViewDelegate <NSObject>
//写一个方法
- (void)presentToViewController;
@end
@interface RootView : UIView
// 2 声明代理人
@property (nonatomic, assign) id<RootViewDelegate>rootDelegate;
//必须用assign的目的是为了防止两个对象之间循环引用
@end
RootView.m
#import "RootView.h"
@interface RootView()
@property(nonatomic,retain)UILabel *alabel;
@end
@implementation RootView
//重写view的初始化方法
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self createSubView];
}
return self;
}
//创建所有子视图
- (void)createSubView{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 50, 30);
btn.backgroundColor = [UIColor grayColor];
[btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
- (void)btnAction:(UIButton *)button{
// 3 执行协议方法
[self.rootDelegate presentToViewController];
}
在RootViewController.m文件里倒入RootView和FirstViewController的头文件
RootViewController.m
#import "RootViewController.h"
#import "FirstViewController.h"
#import "RootView.h"
// 4 签订协议
@interface RootViewController ()<RootViewDelegate>
@property (nonatomic,retain)NSMutableArray *myArr;
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
RootView *rootV = [[RootView alloc] initWithFrame:[[UIScreen mainScreen]bounds]];
rootV.backgroundColor = [UIColor blueColor];
[self.view addSubview:rootV];
[rootV release];
// 5 设置代理人
rootV.rootDelegate = self;
}
// 6 实现协议
- (void)presentToViewController{
NSLog(@"实现协议");
FirstViewController *fvc = [[FirstViewController alloc] init];
//模态的样式
[fvc setModalTransitionStyle:UIModalTransitionStylePartialCurl];
//模态到FirstViewController页面
[self presentViewController:fvc animated:YES completion:^{
}];
}
FirstViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor brownColor];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectMake(100, 100, 20, 20);
[btn addTarget:self action:@selector(check:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)check:(UIButton *)btn{
//模态回去
[self dismissViewControllerAnimated:YES completion:^{
}];
}
协议/代理我标注了6步,这样就可以实现协议了.
简单总结一下两个类之间传值:(C指的是ViewController)
1.C->View传值,单项传值,使用属性,或者方法传值
2.C1->C2之间传值,单向传值,使用属性传值
3.View->C传值(View是加在C上面的),使用协议传值
4.C2->C1传值(C1是C2得上一级页面),使用协议传值