iOS 中控制器间逆向传值的三种方式

在iOS开发中, 我们在两个控制器之间正向传数据的时候, 一般使用的是属性(property), 这样最简单, 最方便, 性能也好

但有时候, 或者说有很多时候, 我们需要逆向传递数据, 也就是当前控制器Dismiss返回上一个控制器时, 在当前控制器处理过的数据需要返回给Source Controller ,这种数据传递, 在OC中一般有三种方式: 通知、代理、Block

1. 通知

在第二个控制器触发Dismiss时, 发出通知, 同时

1
2
3
4
5
- (void)clickDismissButton:(UIButton *)button
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"buttonData" object:nil userInfo:@{@"button":button}];
[self dismissViewControllerAnimated:YES completion:nil]; //也可以在completion的block发出此通知,在此我们不使用回调,给的nil
}

第一个控制器监听此通知即可

1
2
3
4
5
6
7
8
9
10
11
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setTitleText:) name:@"buttonData" object:nil];
}

- (void)setTitleText:(NSNotification *)notify
{
UIButton *button = notify.userInfo[@"button"];
self.receiveLabel.text = button.currentTitle; //我们修改了第一个控制器上一个label的text和背景颜色
self.receiveLabel.backgroundColor = button.backgroundColor;
}//通知其实很简单

2. 代理

因为我们目的是要给第一个控制器传递数据修改属性, 但是第二个控制器做不到修改第一个控制器控件属性这件事儿, 所以, 我们需要在第二个控制器写出协议, 并设置代理属性, 在第一个控制器设置代理, 遵循协议, 实现方法, 也很简单

1
2
3
4
5
6
7
8
9
@class HOModalController;
@protocol HOModalControllerDelegate <NSObject>
@optional
- (void)modalController:(HOModalController *)modalVC withButton:(UIButton *)button;
@end

@interface HOModalController : UIViewController
@property (weak, nonatomic) id <HOModalControllerDelegate> delegate;
@end

并在.m文件中调用代理方法

1
2
3
4
if ([self.delegate respondsToSelector:@selector(modalController:withButton:)])
{
[self.delegate modalController:self withButton:button];
}

在第一个控制控制器中实现代理方法

1
2
3
4
5
- (void)modalController:(HOModalController *)modalVC withButton:(UIButton *)button
{
self.receiveLabel.text = button.currentTitle;
self.receiveLabel.backgroundColor = button.backgroundColor;
}

3. Block

在控制器dismiss的时候, 调用block传值, 首先, 我们在第二个控制器定义一个外部可访问的block属性, 也就是.h文件里

1
@property (copy, nonatomic) void(^modalBlock)(UIButton *button);

然后在.m文件中给此属性赋值

1
self.modalBlock(button);

接着在第一个控制器中调用这个属性即可

1
2
3
4
modalVC.modalBlock = ^(UIButton *button){
self.receiveLabel.text = button.currentTitle;
self.receiveLabel.backgroundColor = button.backgroundColor;
};

0%