控制器之间的数据传递——Block传值

时间:2021-08-31 19:11:10

Block传值

我们先在这里约定:界面1传值到界面2为顺传,界面2传值到界面1为逆传

一般用Block传值是为了降低视图控制器之间的耦合度,和代理传值类似主要用于逆序传值。

一. 实现步骤

  1. 给界面2定义一个Block属性;注意:在block传值中,要传几个值,block就有几个参数,参数要与传的值对应

  2. 在界面2的跳转方法中检查block属性是否有值,有值就执行block,然后界面2出栈

  3. 在界面1的跳转方法中创建界面2,并把要执行的赋值语句保存到界面2的block变量属性

二. 具体代码

1. AppDelegate类

---------- AppDelegate.m文件

#import "AppDelegate.h"
#include "OneViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 1. 创建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

// 2. 创建窗口的根控制器
// 2.1 创建导航控制器的根控制器
UIViewController *oneVc = [[OneViewController alloc] init];
// 2.2 创建导航控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:oneVc];
// 2.3 给窗口设置根控制器
self.window.rootViewController = nav;

// 3. 设置窗口为主窗口并显示窗口
[self.window makeKeyAndVisible];

// 隐藏导航控制器的导航条
nav.navigationBarHidden = YES;

return YES;
}

@end

2. OneViewController类

---------- OneViewController.m文件

#import "OneViewController.h"
#import "TwoViewController.h"

@interface OneViewController ()

@property (nonatomic,strong) UITextField *textField;

@end

@implementation OneViewController

- (void)viewDidLoad {
[super viewDidLoad];

//设置控制器View的背景颜色
self.view.backgroundColor = [UIColor greenColor];

// 创建点击按钮
UIButton *clickBtn = [UIButton buttonWithType:UIButtonTypeCustom];
clickBtn.frame = CGRectMake(10, 100, 80, 40);
clickBtn.backgroundColor = [UIColor whiteColor];
[clickBtn setTitle:@"到界面2" forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[clickBtn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:clickBtn];

// 创建文本框
_textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 150, 250, 40)];
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_textField];

}

#pragma mark - 点击事件

- (void)btnClick {

// 创建界面2,并压入栈
TwoViewController *twoVc = [[TwoViewController alloc] init];
[self.navigationController pushViewController:twoVc animated:YES];

// 给界面的Block设置传值代码块
twoVc.twoBlock = ^(NSString *str){
// 用界面2的值赋给界面1的文本框,这句代码是在界面1中执行的
_textField.text = str;
};

}

@end

3. TwoViewController类

---------- TwoViewController.h文件

#import <UIKit/UIKit.h>

// 自定义一个Block变量类型名
typedef void(^TwoViewControllerBlock)(NSString *);

@interface TwoViewController : UIViewController

// Block属性
@property (nonatomic,strong) TwoViewControllerBlock twoBlock;

@end

---------- TwoViewController.h文件

#import "TwoViewController.h"

@interface TwoViewController ()

@property (nonatomic,strong) UITextField *textField;

@end

@implementation TwoViewController

- (void)viewDidLoad {
[super viewDidLoad];

//设置控制器View的背景颜色
self.view.backgroundColor = [UIColor yellowColor];

// 创建点击按钮
UIButton *clickBtn = [UIButton buttonWithType:UIButtonTypeCustom];
clickBtn.frame = CGRectMake(10, 100, 80, 40);
clickBtn.backgroundColor = [UIColor whiteColor];
[clickBtn setTitle:@"传 值" forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[clickBtn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[clickBtn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:clickBtn];

// 创建文本框
_textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 150, 250, 40)];
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_textField];
}

#pragma mark - 点击事件

- (void)btnClick {

// 如果Block有值就执行Block
if (_twoBlock) {
// 传入文本框的值传到界面1
_twoBlock(_textField.text);
}

// 跳转界面
[self.navigationController popViewControllerAnimated:YES];

}

@end