一、是什么?用来干什么?
代理是iOS里面的一种设计模式,使用代理可以实现监听和传参。这种模式用于一个对象“代表”另外一个对象去做和实现一些东西。
二、谁是谁的代理?
举个简单例子,比如A控制器和B控制器,假定A控制器有某一个按钮且被点击了,这时B控制器想知道A控制器按钮被点击了,也就是B想监听A何时被点击,那么我们可以说B是A的代理。
三、实现代理步骤
1.接下面的演示都是设定了B是A的代理,为了监听A控制器里的BTN被点击了。首先我们在A控制器.h里定义一个代理属性和协议,假设A控制器名:YMView
//ID 是为了避免耦合,任何控制器都可以用这个代理,YMViewDelegate 是为了告诉代理去遵守这个协议
@property (nonatomic, weak) id<YMViewDelegate> delegate;
//写protocol协议,最好命名类名+delegate,optional是为了让这个协议方法并不强求去实现 ,YMViewDidClickedLoadBtn为协议方法。
//定义协议,建立方法,这样代理才可运用。
@protocol YMViewDelegate <NSObject>
@optional
- (void)YMViewDidClickedLoadBtn:(YMView *) logView;
@end
上面几句在A控制器里面的代码就算把代理先设定好了。
然后在A控制器的.m文件里按钮被点击时,完成下面if判断执行代码方法
//didlog为A控制器的按钮点击方法
-(void)didlog{
//A控制器被点击,[self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]是为了检测代理控制器也就是A控制器有没有实现这个协议方法,没有就不执行括号里面的东西了。
if ([self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]) {
//被点了,通知代理B调用YMViewDidClickedLoadBtn方法。
[self.delegate YMViewDidClickedLoadBtn:self];
}
}
接着就是让代理控制器也就是B控制器去遵守代理协议,这里设B控制器为viewcontroller
@interface ViewController ()<YMViewDelegate>
然后让B控制器成为A的代理
YMView *ym=[[YMView alloc]init];
//设置B控制器为A控制器的代理
ym.delegate=self;
最后B控制器实现代理方法
//代理调用了代理方法
-(void)YMViewDidClickedLoadBtn:(YMView *)logView{
NSLog(@"B控制器监听到了A控制器按钮被点击");
}
四、完整代码
代码表示的是控制器当B点击了BTN跳转到A,A里面有一个按钮,A里面的按钮被点击时通知B执行代理,这里设定B控制器为viewcontroller,A控制器为YMview
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h"
#import "YMView.h"
@interface ViewController ()<YMViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//定义BTN为了push A控制器而已,跟代理无关
UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(200, 200, 100, 100)];
btn.backgroundColor=[UIColor grayColor];
[btn addTarget:self action:@selector(pushA) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)pushA{
YMView *ym=[[YMView alloc]init];
//设置B控制器为A控制器的代理
ym.delegate=self;
[self.navigationController pushViewController:ym animated:YES];
}
//代理调用了代理方法
-(void)YMViewDidClickedLoadBtn:(YMView *)logView{
NSLog(@"B控制器监听了A控制器按钮被点击");
}
#import <UIKit/UIKit.h>
@class YMView;
//定义协议,建立方法,这样代理才可运用。
@protocol YMViewDelegate <NSObject>
@optional
- (void)YMViewDidClickedLoadBtn:(YMView *) logView;
@end
@interface YMView : UIViewController
//设定代理属性
@property (nonatomic, weak) id<YMViewDelegate> delegate;
@end
#import "YMView.h"
@interface YMView ()
@end
@implementation YMView
- (void)viewDidLoad {
[super viewDidLoad];
//定义BTN为了测试代理
UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
btn.backgroundColor=[UIColor grayColor];
[btn addTarget:self action:@selector(didlog) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)didlog{
//A控制器被点击,[self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]是为了检测代理控制器也就是A控制器有没有实现这个协议方法,没有就不执行括号里面的东西了。
if ([self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]) {
//通知代理调用YMViewDidClickedLoadBtn方法。
[self.delegate YMViewDidClickedLoadBtn:self];
}
}
@end
此部分内容暂未涉及传参