欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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.备注

  1. 代理实现了不同视图之间的数据交互,只有某一事件触发才会被调用,在使用代理时,代理者要遵循代理,设置代理,实现代理方法,只有设置了代理,才能调用代理方法。

  2. 委托类中需要声明相应协议,类型为id,用nonatomic和weak进行修饰,防止循环引用。

  3. 在委托类的实现文件中,需要触发代理事件的地方通过self.delegate来调用方法

  4. 在代理类的实现文件中,需要导入头文件,并遵循代理。

 

参考:

iOS中delegate的使用

 

 

本文地址:https://blog.csdn.net/qq_41843697/article/details/108185422

相关标签: IOS开发基础 ios