iOS开发基础-delegate(委托)
程序员文章站
2022-07-03 15:07:42
1.定义代理设计模式,是IOS中一种消息传递的方式,由代理对象、委托者、协议组成。协议:用来指定代理可以做什么,必须做什么代理:根据指定协议,完成委托方需要实现的方法委托:根据指定协议,指定代理必须完成和可以完成的方法2.作用传值(逆向传值)传递事件3.传值声明协议:NextViewController.h#import NS_ASSUME_NONNULL_BEGIN//声明协议...
1.定义
代理设计模式,是IOS中一种消息传递的方式,由代理对象、委托者、协议组成。
-
协议:用来指定代理可以做什么,必须做什么
-
代理:根据指定协议,完成委托方需要实现的方法
-
委托:根据指定协议,指定代理必须完成和可以完成的方法
2.作用
-
传值(逆向传值)
-
传递事件
3.传值
声明协议:
NextViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
//声明协议
@protocol NextViewControllerDelegate <NSObject>
//协议中必须完成的方法
- (void)sendValue:(NSString *)string;
@end
@interface NextViewController : UIViewController
//持有delegate的为委托者
@property (nonatomic, weak) id<NextViewControllerDelegate> delegate;
@end
NS_ASSUME_NONNULL_END
委托者(指定代理需要完成的方法):
NextViewController.m
#import "NextViewController.h"
@interface NextViewController ()
//委托者
@property (nonatomic, strong) UITextField *sendValueTextField;
@property (nonatomic, strong) UIButton *backButton;
@end
@implementation NextViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//输入值的位置
self.sendValueTextField = [[UITextField alloc] initWithFrame:CGRectMake(5, 90, self.view.frame.size.width - 10, 200)];
self.sendValueTextField.borderStyle = UITextBorderStyleLine;
self.sendValueTextField.placeholder = @"请输入要传递的值";
[self.view addSubview:self.sendValueTextField];
//返回上一页面按钮
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.backButton.frame = CGRectMake(0, 300, 150, 50);
[self.backButton setTitle:@"返回上一控制器" forState:UIControlStateNormal];
self.backButton.center = self.view.center;
[self.view addSubview:self.backButton];
[self.backButton addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)clickBtn:(UIButton *) sender {
//返回上一页面
[self.navigationController popViewControllerAnimated:YES];
NSString *str = self.sendValueTextField.text;
if(str.length > 0) {
//如果本框中有内容,则指定代理必须完成的方法
if([self.delegate respondsToSelector:@selector(sendValue:)]) {
[self.delegate sendValue:str];
}
}
}
@end
代理者:实现协议中的方法
ViewController.m
#import "ViewController.h"
#import "NextViewController.h"
@interface ViewController ()<NextViewControllerDelegate>
//代理
@property (nonatomic, strong) UITextField *getTextField;
@property (nonatomic, strong) UIButton *nextButton;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
//进入下一个页面的按钮
self.nextButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.nextButton.frame = CGRectMake(20, 90, 100, 50);
[self.nextButton setTitle:@"进入下一页面" forState:UIControlStateNormal];
[self.view addSubview:self.nextButton];
[self.nextButton addTarget:self action:@selector(pushNext:) forControlEvents:UIControlEventTouchUpInside];
//从下一个页面返回的值
self.getTextField = [[UITextField alloc] initWithFrame:CGRectMake(5, 200, self.view.frame.size.width - 10, 200)];
self.getTextField.textAlignment = 1;
self.getTextField.borderStyle = UITextBorderStyleLine;
self.getTextField.placeholder = @"获得的值";
[self.view addSubview:self.getTextField];
}
- (void)pushNext:(UIButton *)sender {
//进入下一个页面
NextViewController *nextVC = [[NextViewController alloc] init];
[self.navigationController pushViewController:nextVC animated:YES];
//核心语句,设置下一个页面的代理为本页面
nextVC.delegate = self;
}
- (void)sendValue:(nonnull NSString *)string {
//代理需要完成的委托方需要实现的方法
self.getTextField.text = string;
}
@end
4.传递事件
协议
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
//声明代理
@protocol FunViewDelegate <NSObject>
- (void)viewDelegateFunc;
@end
@interface MyView : UIView
//持有代理
@property (nonatomic, weak) id<FunViewDelegate> viewDelegate;
@end
NS_ASSUME_NONNULL_END
委托者
#import "MyView.h"
@implementation MyView
//定义方法
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//让代理者执行代理方法
if([self.viewDelegate respondsToSelector:@selector(viewDelegateFunc)]) {
[self.viewDelegate viewDelegateFunc];
}
}
@end
代理者
@interface ViewController ()<FunViewDelegate>
//代理类
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
MyView *view = [[MyView alloc] init];
//核心语句,设置view的代理为本控制器,否则无法进行代理
view.viewDelegate = self;
view.frame = CGRectMake(0, 0, 60, 70);
//设置MyView的中心就是self.view的中心,这样上面一句的位置就可以都设置为0
//开发中经常用这种逻辑,首先设置frame的时候位置都设置为0,位置在后面再设置
view.center = self.view.center;
view.backgroundColor = [UIColor greenColor];
//打开交互设置,可交互
view.userInteractionEnabled = YES;
[self.view addSubview:view];
}
#pragma mark - viewDelegateFunc代理方法
- (void) viewDelegateFunc {
//指定代理方法
NSLog(@"myViewDelegate的代理,点击view");
}
@end
5.备注
-
代理实现了不同视图之间的数据交互,只有某一事件触发才会被调用,在使用代理时,代理者要遵循代理,设置代理,实现代理方法,只有设置了代理,才能调用代理方法。
-
委托类中需要声明相应协议,类型为id,用nonatomic和weak进行修饰,防止循环引用。
-
在委托类的实现文件中,需要触发代理事件的地方通过self.delegate来调用方法
-
在代理类的实现文件中,需要导入头文件,并遵循代理。
参考:
本文地址:https://blog.csdn.net/qq_41843697/article/details/108185422