当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS开发基础-delegate(委托)

iOS开发基础-delegate(委托)

2020年08月01日  | 移动技术网移动技术  | 我要评论
1.定义代理设计模式,是IOS中一种消息传递的方式,由代理对象、委托者、协议组成。协议:用来指定代理可以做什么,必须做什么代理:根据指定协议,完成委托方需要实现的方法委托:根据指定协议,指定代理必须完成和可以完成的方法2.作用传值(逆向传值)传递事件3.传值声明协议:NextViewController.h#import <UIKit/UIKit.h>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

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网