经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
iOS学习——页面的传值方式
来源:cnblogs  作者:mukekeheart  时间:2019/3/8 8:58:40  对本文有异议

一、简述

  在iOS开发过程中,页面跳转时在页面之间进行数据传递是很常见的事情,我们称这个过程为页面传值。页面跳转过程中,从主页面跳转到子页面的数据传递称之为正向传值;反之,从子页面返回主页面时的数据传递称之为反向传值

  目前我所了解和掌握的传值方式有:

  1. 性传值
  2. 单例传值
  3. NSUserDefaults传值
  4. 代理传值
  5. block传值
  6. 通知传值
  7. KVO/KVC  iOS----KVC和KVO 详解

二、页面传值的详解

2.0 准备工作

  为了实现页面之间传值,我们需要准备两个页面,代码结构如下图所示。其中,KLMainViewController为主主页面,KLSubViewController为子页面,页面之间的跳转使用UINavigationController来实现。每个页面中都有一个文本编辑框,我们需要将其中一个页面文本框中的内容传递到另一个页面中。

         

  1. 1 #import "KLMainViewController.h"
  2. 2 #import "KLSubViewController.h"
  3. 3
  4. 4 @interface KLMainViewController ()
  5. 5
  6. 6 @property (strong, nonatomic) UITextField *textField;
  7. 7 @property (strong, nonatomic) UIButton *button;
  8. 8
  9. 9 @end
  10. 10
  11. 11 @implementation KLMainViewController
  12. 12
  13. 13 - (void)viewDidLoad {
  14. 14 [super viewDidLoad];
  15. 15 self.title = @"主界面";
  16. 16
  17. 17 _textField = [[UITextField alloc] init];
  18. 18 _textField.textColor = [UIColor redColor];
  19. 19 _textField.textAlignment = NSTextAlignmentCenter;
  20. 20 _textField.backgroundColor = kBgColor;
  21. 21 _textField.text = @"主界面的label信息";
  22. 22 [self.view addSubview:_textField];
  23. 23 WEAKSELF
  24. 24 [_textField mas_makeConstraints:^(MASConstraintMaker *make) {
  25. 25 make.center.mas_equalTo(weakSelf.view).mas_offset(0.0f);
  26. 26 make.left.mas_equalTo(weakSelf.view).mas_offset(15.0f);
  27. 27 make.right.mas_equalTo(weakSelf.view).mas_offset(-15.0f);
  28. 28 }];
  29. 29
  30. 30 _button = [UIButton buttonWithType:UIButtonTypeCustom];
  31. 31 [_button setTitle:@"跳转到子界面" forState:UIControlStateNormal];
  32. 32 [_button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
  33. 33 [_button addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
  34. 34 [self.view addSubview:_button];
  35. 35 [_button mas_makeConstraints:^(MASConstraintMaker *make) {
  36. 36 make.centerX.mas_equalTo(weakSelf.view).mas_offset(0.0f);
  37. 37 make.top.mas_equalTo(weakSelf.textField.mas_bottom).mas_offset(40.0f);
  38. 38 }];
  39. 39
  40. 40 }
  41. 41
  42. 42 - (void) btnClicked:(UIButton *)btn {
  43. 43 KLSubViewController *subVC = [[KLSubViewController alloc] init];
  44. 44 [self.navigationController pushViewController:subVC animated:YES];
  45. 45 }
  46. 46
  47. 47 @end
KLMainViewController.m
  1. 1 //KLSubViewController.h
  2. 2 #import <UIKit/UIKit.h>
  3. 3
  4. 4 NS_ASSUME_NONNULL_BEGIN
  5. 5
  6. 6 @interface KLSubViewController : UIViewController
  7. 7
  8. 8 @property (strong, nonatomic) UITextField *textField;
  9. 9 @property (strong, nonatomic) UIButton *button;
  10. 10
  11. 11 @property (strong, nonatomic) NSString *content;
  12. 12
  13. 13 @end
  14. 14
  15. 15 NS_ASSUME_NONNULL_END
  16. 16
  17. 17 //KLSubViewController.m
  18. 18 #import "KLSubViewController.h"
  19. 19
  20. 20 @interface KLSubViewController ()
  21. 21
  22. 22 @end
  23. 23
  24. 24 @implementation KLSubViewController
  25. 25
  26. 26 - (void)viewDidLoad {
  27. 27 [super viewDidLoad];
  28. 28 self.view.backgroundColor = [UIColor whiteColor];
  29. 29 self.title = @"子界面";
  30. 30
  31. 31 _textField = [[UITextField alloc] init];
  32. 32 _textField.textColor = [UIColor redColor];
  33. 33 _textField.textAlignment = NSTextAlignmentCenter;
  34. 34 _textField.backgroundColor = kBgColor;
  35. 35 _textField.text = @"子界面的label信息";
  36. 36 [self.view addSubview:_textField];
  37. 37 WEAKSELF
  38. 38 [_textField mas_makeConstraints:^(MASConstraintMaker *make) {
  39. 39 make.center.mas_equalTo(weakSelf.view).mas_offset(0.0f);
  40. 40 make.left.mas_equalTo(weakSelf.view).mas_offset(15.0f);
  41. 41 make.right.mas_equalTo(weakSelf.view).mas_offset(-15.0f);
  42. 42 }];
  43. 43
  44. 44 _button = [UIButton buttonWithType:UIButtonTypeCustom];
  45. 45 [_button setTitle:@"返回主界面" forState:UIControlStateNormal];
  46. 46 [_button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
  47. 47 [_button addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
  48. 48 [self.view addSubview:_button];
  49. 49 [_button mas_makeConstraints:^(MASConstraintMaker *make) {
  50. 50 make.centerX.mas_equalTo(weakSelf.view).mas_offset(0.0f);
  51. 51 make.top.mas_equalTo(weakSelf.textField.mas_bottom).mas_offset(40.0f);
  52. 52 }];
  53. 53 }
  54. 54
  55. 55 - (void) btnClicked:(UIButton *)btn {
  56. 56
  57. 57 [self.navigationController popViewControllerAnimated:YES];
  58. 58 }
  59. 59
  60. 60 @end
KLSubViewController

2.1 属性传值

方法描述:在从当前页面跳转到下主页面之前,提前创建下主页面,通过赋值的方式将当前页面的数据赋予下主页面的属性。

适用场景:当从主页面push到子页面时,子页面需要使用到主页面的数据,我们需要使用到正向传值。

传递方式:正向传值。

使用步骤

  1. 子页面的.h文件中定义属性来保留要传递过来的数据
    1. //子页面KLSubViewController.h的属性定义
    2. @interface KLSubViewController : UIViewController
    3. @property (strong, nonatomic) UITextField *textField;
    4. @property (strong, nonatomic) UIButton *button;
    5. @property (strong, nonatomic) NSString *content;//属性接收数据
    6.  
    7. @end
  2. 主页面在跳转的时候将数据赋值给子页面对应的属性 
    1. //主界面跳转时将数据赋值给对应的属性
    2. @interface KLMainViewController ()
    3. @property (strong, nonatomic) UITextField *textField;
    4. @property (strong, nonatomic) UIButton *button;
    5. @end
    6.  
    7. @implementation KLMainViewController
    8. - (void)viewDidLoad {
    9. [super viewDidLoad];
    10. self.title = @"主界面";
    11. //布局代码省略
    12. ......
    13. }
    14. //跳转
    15. - (void) btnClicked:(UIButton *)btn {
    16. KLSubViewController *subVC = [[KLSubViewController alloc] init];
    17. subVC.content = @"来自主界面的数据";
    18. // subVC.textField.text = @"来自主界面的数据"; //这样传递是有问题的,因为子页面中的textfield是在viewDidLoad中进行初始化和布局的,在这时候textfield还没有初始化,为nil,所以赋值是失效的
    19. [self.navigationController pushViewController:subVC animated:YES];
    20. }
    21. @end

2.2 代理传值

方法描述:首先在子页面的头文件中添加一个代理(协议)的定义,定义一个传递数据的方法,并且在子页面的类中添加一个代理属性;然后,在子页面返回主页面之前调用代理中定义的数据传递方法(方法参数就是要传递的数据);最后,在主页面中遵从该代理,并实现代理中定义的方法,在方法的实现代码中将参数传递给主页面的属性。

适用场景:已经通过push的方式进入到子页面,在从子页面返回主页面的时候(子页面会释放掉内存),需要在主页面中使用子页面中的数据,这是就可以利用代理反向传值。

传递方式:反向传值。

使用步骤

  1. 在子页面中添加一个代理协议,在协议中定义一个传递数据的方法
  2. 在子页面.h文件中添加一个代理属性
    1. //子页面的.h文件,定义代理以及代理属性
    2. // 声明代理
    3. @protocol BToADelegate <NSObject>
    4. // 代理方法
    5. - (void)transferString:(NSString *)string;
    6. @end
    7.  
    8. @interface KLSubViewController : UIViewController
    9. @property (strong, nonatomic) UITextField *textField;
    10. @property (strong, nonatomic) UIButton *button;
    11. @property (nonatomic, weak) id<BToADelegate> delegate;//代理属性
    12.  
    13. @end
  3. 在子页面返回主页面之前掉好用代理中定义数据传递方法,方法参数就是要传递的数据
    1. //子页面返回时调用代理方法
    2. - (void) btnClicked:(UIButton *)btn {
    3. //如果当前的代理存在,并且实现了代理方法,则调用代理方法进行传递数据
    4. if (self.delegate &&
    5. [self.delegate respondsToSelector:@selector(transferString:)]) {
    6. [self.delegate transferString:@"子页面回传的数据"];
    7. }
    8. [self.navigationController popViewControllerAnimated:YES];
    9. }
  4. 在主页面中遵从该代理,并实现代理中定义的方法,在方法的实现代码中将参数传递给主页面的属性
    1. //要实现BToADelegate
    2. @interface KLMainViewController () <BToADelegate>
    3. @property (strong, nonatomic) UITextField *textField;
    4. @property (strong, nonatomic) UIButton *button;
    5. @end
    6.  
    7. @implementation KLMainViewController
    8. - (void)viewDidLoad {
    9. [super viewDidLoad];
    10. self.title = @"主界面";
    11. //布局代码省略
    12. ...
    13. }
    14. - (void) btnClicked:(UIButton *)btn {
    15. KLSubViewController *subVC = [[KLSubViewController alloc] init];
    16. subVC.delegate = self; //申明子页面的代理是主页面自身self
    17. [self.navigationController pushViewController:subVC animated:YES];
    18. }
    19. #pragma mark BToADelegate 代理方法,子页面调用的时候会回调该方法
    20. - (void)transferString:(NSString *)string {
    21. self.textField.text = string;
    22. }
    23. @end

 2.3 Block传值

方法描述:在子页面中添加一个块语句属性,在子页面返回主页面之前调用该块语句。在主页面跳转子页面之前,设置子页面中的块语句属性将要执行的动作(回调函数)。这样,在子页面返回主页面时就会调用该回调函数来传递数据。

适用场景:已经通过push的方式进入到子页面,在从子页面返回主页面的时候(子页面会释放掉内存),需要在主页面中使用子页面中的数据,这是就可以利用代理反向传值。

传递方式:反向传递。

使用步骤:整个步骤和代理差不多

  1. 在子页面中添加一个块语句属性
    1. //定义block的类型
    2. typedef void (^TransDataBlock)(NSString *content);
    3. @interface KLSubViewController : UIViewController
    4. @property (strong, nonatomic) UITextField *textField;
    5. @property (strong, nonatomic) UIButton *button;
    6. @property (copy, nonatomic) TransDataBlock transDataBlock;//定义一个block属性,用于回传数据
    7.  
    8. @end
  2. 在子页面返回主页面之前调用该块语句
    1. #import "KLSubViewController.h"
    2.  
    3. @interface KLSubViewController ()
    4. @end
    5.  
    6. @implementation KLSubViewController
    7. - (void)viewDidLoad {
    8. [super viewDidLoad];
    9. self.view.backgroundColor = [UIColor whiteColor];
    10. self.title = @"子界面";
    11. //布局代码省略
    12. ......
    13. }
    14. - (void) btnClicked:(UIButton *)btn {
    15. //如果回传block存在 则调用该block进行回传数据
    16. if (self.transDataBlock) {
    17. self.transDataBlock(@"子页面回传的数据");
    18. }
    19. [self.navigationController popViewControllerAnimated:YES];
    20. }
    21. @end
  3. 在主页面跳转子页面之前,设置子页面中的块语句属性将要执行的动作(回调函数)
    1. #import "KLMainViewController.h"
    2. #import "KLSubViewController.h"
    3.  
    4. @interface KLMainViewController ()
    5. @property (strong, nonatomic) UITextField *textField;
    6. @property (strong, nonatomic) UIButton *button;
    7. @end
    8.  
    9. @implementation KLMainViewController
    10. - (void)viewDidLoad {
    11. [super viewDidLoad];
    12. self.title = @"主界面";
    13. //布局代码省略
    14. ......
    15. }
    16. - (void) btnClicked:(UIButton *)btn {
    17. KLSubViewController *subVC = [[KLSubViewController alloc] init];
    18. //通过子页面的block回传拿到数据后进行处理,赋值给当前页面的textfield
    19. subVC.transDataBlock = ^(NSString *content) {
    20. self.textField.text = content;
    21. };
    22. [self.navigationController pushViewController:subVC animated:YES];
    23. }
    24. @end 

2.4 通知传值

方法描述:在通知接收方需要注册通知,并指定接收到通知后进行的操作;而在通知发送方则在需要传递数据时发送通知就OK了。通知的操作都是通过NSNotificationCenter来完成的。

但是要注意的两点是:

  • 要想能够接收到通知进行处理,必须先注册通知。
  • 在注册通知的页面消毁时一定要移除已经注册的通知,否则会造成内存泄漏
  • 注册的接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知

适用场景

  • 一般用于已经通过push的方式进入到子页面,在从子页面返回主页面的时候(子页面会释放掉内存),需要在主页面中使用子页面中的数据,这是就可以利用通知反向传值。
  • 但是也可以用于通过push进入子页面时向子页面传递数据,这时就可以用通知进行正向传值。

传递方式:正向传递(很少这样用)、反向传递(更常用)。

使用步骤

  • 反向传递:
  1. 在子页面返回的时候发送通知,注册的接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知
    1. @interface KLSubViewController ()
    2. @end
    3.  
    4. @implementation KLSubViewController
    5. - (void)viewDidLoad {
    6. [super viewDidLoad];
    7. self.view.backgroundColor = [UIColor whiteColor];
    8. self.title = @"子界面";
    9. //布局代码省略
    10. .......
    11. }
    12. - (void) btnClicked:(UIButton *)btn {
    13. //发送通知回传数据,回传的数据格式自定义,这里定义为dictionary类型
    14. [[NSNotificationCenter defaultCenter] postNotificationName:@"TransDataNoti" object:nil userInfo:@{@"content":@"子页面回传的数据"}];
    15. [self.navigationController popViewControllerAnimated:YES];
    16. }
  2. 在主页面注册通知,并制定接收到通知后执行的操作方法。需要注意的是,在注册通知的页面消毁时一定要移除已经注册的通知,否则会造成内存泄漏。
    1. @interface KLMainViewController ()
    2. @property (strong, nonatomic) UITextField *textField;
    3. @property (strong, nonatomic) UIButton *button;
    4. @end
    5.  
    6. @implementation KLMainViewController
    7. - (void)dealloc {
    8. //移除所有通知
    9. [[NSNotificationCenter defaultCenter] removeObserver:self];
    10. // 移除某个
    11. // [[NSNotificationCenter defaultCenter] removeObserver:self name:@"TransDataNoti" object:nil];
    12. }
    13. - (void)viewDidLoad {
    14. [super viewDidLoad];
    15. self.title = @"主界面";
    16. //布局代码省略
    17. ......
    18. //注册通知,用于接收通知,接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知
    19. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiReceived:) name:@"TransDataNoti" object:nil];
    20. }
    21. //接收通知,解析内容进行处理
    22. - (void)notiReceived:(NSNotification *)sender {
    23. self.textField.text = sender.userInfo[@"content"];
    24. }
    25. - (void) btnClicked:(UIButton *)btn {
    26. KLSubViewController *subVC = [[KLSubViewController alloc] init];
    27. [self.navigationController pushViewController:subVC animated:YES];
    28. }
    29. @end
  •  正向传递:和反向传递的不走基本就是反过来就OK了,但是有一点需要注意的是正向传递时从主界面push到子界面时发送通知,这时候要确保子界面已经注册了通知,否则会收不到通知的,所以正向传递时,子界面通知的注册应该在子界面的初始化init方法中进行。
  1. 在主页面返回的时候发送通知,注册的接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知。
    1. @interface KLMainViewController ()
    2. @property (strong, nonatomic) UITextField *textField;
    3. @property (strong, nonatomic) UIButton *button;
    4. @end
    5.  
    6. @implementation KLMainViewController
    7. - (void)viewDidLoad {
    8. [super viewDidLoad];
    9. self.title = @"主界面";
    10. //布局代码省略
    11. ......
    12. }
    13. - (void) btnClicked:(UIButton *)btn {
    14. KLSubViewController *subVC = [[KLSubViewController alloc] init];
    15. //发送通知回传数据,回传的数据格式自定义,这里定义为dictionary类型
    16. [[NSNotificationCenter defaultCenter] postNotificationName:@"TransDataNoti" object:nil userInfo:@{@"content":@"主页面传递的数据"}];
    17. [self.navigationController pushViewController:subVC animated:YES];
    18. }
    19. @end
  2. 在子页面注册通知,并制定接收到通知后执行的操作方法。正向传递时注册通知、基本布局不能放在viewDidLoad中,要放在初始化函数init中。
    1. @interface KLSubViewController ()
    2. @end
    3.  
    4. @implementation KLSubViewController
    5. - (void)dealloc {
    6. //移除所有通知
    7. [[NSNotificationCenter defaultCenter] removeObserver:self];
    8. // 移除某个
    9. // [[NSNotificationCenter defaultCenter] removeObserver:self name:@"TransDataNoti" object:nil];
    10. }
    11. - (instancetype)init {
    12. self = [super init];
    13. //初始化代码省略
    14. ......
    15. //注册通知,用于接收通知,接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知
    16. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiReceived:) name:@"TransDataNoti" object:nil];
    17. return self;
    18. }
    19. - (void)viewDidLoad {
    20. [super viewDidLoad];
    21. self.view.backgroundColor = [UIColor whiteColor];
    22. self.title = @"子界面";
    23. }
    24. //接收通知,解析内容进行处理
    25. - (void)notiReceived:(NSNotification *)sender {
    26. self.textField.text = sender.userInfo[@"content"];
    27. }
    28. - (void) btnClicked:(UIButton *)btn {
    29. [self.navigationController popViewControllerAnimated:YES];
    30. }
    31. @end

2.5 NSUserDefaults传值

方法描述:NSUserDefaults传值是将所要传的值写在沙盒目录里面,需要获取值的时候直接访问沙盒,获取这个值就可以了,这种传值方法一般用在需要将数据本地存储的时候,比如:用户名之类,当用户下次登录或者使用app的时候,可以直接从本地读取。

适用场景:任何需要数据传递的场景都适用,但是传递数据的类型仅限于基本数据类型,不能用于自定义的对象类型。

传递方式:正向传值、反向传值。

使用步骤

  1. 需要传值时将数据通过NSUserDefaults保存到沙盒目录里面
    1. - (void) btnClicked:(UIButton *)btn {
    2. /*
    3. setObject:后面写的就是所需要传递的值
    4. forKey:要具有唯一性、一致性;
    5. 唯一性是指:当代码中用到多个NSUserDefaults方法时,要保证不同的key不一样,否则就是覆盖值
    6. 一致性:这里传递一个值,当需要用到的时候,要用valueForkey的方法,这个key和传值时候写的key要一样,写错了就找不到值了。
    7. */
    8. [[NSUserDefaults standardUserDefaults] setObject:@"NSUserDefaults传值" forKey:@"NSUserDefaults"];
    9. [[NSUserDefaults standardUserDefaults] synchronize];
    10. [self.navigationController popViewControllerAnimated:YES];
    11. }
  2. 需要使用值时通过NSUserDefaults从沙盒目录里面取值进行处理
    1. _label.text = [[NSUserDefaults standardUserDefaults] valueForKey:@"NSUserDefaults"];

2.6 单例传值

方法描述:单例传值的性质和NSUserDefaults传值的性质类似,只是单例传值是将数据保存在单例对象中,需要的时候同样从单例对象中去获取数据使用就ok。

适用场景:任何需要数据传递的场景都适用,传递的数据可以是任何类型的数据。

传递方式:正向传值、反向传值均OK。

使用步骤

  1. 创建一个类,拥有一些属性用于保存数据,并实现单例方法
    1. @interface KLDanliObj : NSObject
    2. @property (nonatomic, copy) NSString *content; //保存数据数据的属性
    3.  
    4. + (instancetype) shardDanLiObj; //单例对象获取方法
    5.  
    6. @end
    1. #import "KLDanliObj.h"
    2.  
    3. static DanLi *danli = nil;
    4. @implementation KLDanliObj
    5. + (instancetype) shardDanLiObj {
    6. //实现方法,判断是否为空,是就创建一个全局实例给它
    7. if (danli == nil) {
    8. danli = [[KLDanliObj alloc] init];
    9. }
    10. return danli;
    11. }
    12. @end
  2. 需要传递数据时使用单例类将数据保存到单例的属性中
    1. [KLDanliObj shardDanLiObj].content = @"主界面传递的数据"; 
  3. 需要使用值时通过单例的属性获取数据进行使用和处理
    1. self.textField.text = [KLDanliObj shardDanLiObj].content; 

2.7 KVC传值

方法描述:KVC(Key-value coding)键值编码,单看这个名字可能不太好理解。其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值,而不需要调用明确的存取方法,这样就可以在运行时动态地访问和修改对象的属性。这其实和属性传值比较类似。

适用场景:当从主页面push到子页面时,子页面需要使用到主页面的数据,我们需要使用到正向传值。

传递方式:正向传值

使用步骤

  1. 在需要传值时使用KVC给子页面的属性进行赋值就ok了
    1. - (void) btnClicked:(UIButton *)btn {
    2. KLSubViewController *subVC = [[KLSubViewController alloc] init];
    3. //给子页面subVC的属性content赋值 和subVC.content = @"主页面传递的数据";效果一样
    4. [subVC setValue:@"主页面传递的数据" forKey:@"content"];
    5. [self.navigationController pushViewController:subVC animated:YES];
    6. } 

2.8 KVO传值

方法描述:KVO(Key-Value-Observing,键值观察),即观察关键字的值的变化。首先在子页面中声明一个待观察的属性,在返回主页面之前修改该属性的值。在主页面中提前分配并初始化子页面,并且注册对子页面中对应属性的观察者。在从子页面返回上主之前,通过修改观察者属性的值,在主页面中就能自动检测到这个改变,从而读取子页面的数据。

适用场景:已经通过push的方式进入到子页面,在从子页面返回主页面的时候(子页面会释放掉内存),需要在主页面中使用子页面中的数据,这是就可以利用代理反向传值。

传递方式:反向传递。

使用步骤

  1. 在主页面注册观察者,实现KVO的回调方法,并在主页面销毁时移除观察者
    1. @interface KLMainViewController ()
    2. @property (strong, nonatomic) UITextField *textField;
    3. @property (strong, nonatomic) UIButton *button;
    4. @property (strong, nonatomic) KLSubViewController *subVC;
    5. @end
    6.  
    7. @implementation KLMainViewController
    8. - (void)dealloc {
    9. //移除观察者
    10. [self.subVC removeObserver:self forKeyPath:@"content"];
    11. }
    12. - (void)viewDidLoad {
    13. [super viewDidLoad];
    14. self.title = @"主界面";
    15. //布局代码省略
    16. .......
    17. }
    18. - (void) btnClicked:(UIButton *)btn {
    19. if (!_subVC) {
    20. _subVC = [[KLSubViewController alloc] init];
    21. //注册观察者
    22. [_subVC addObserver:self forKeyPath:@"content" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil];
    23. }
    24. [self.navigationController pushViewController:_subVC animated:YES];
    25. }
    26. // KVO的回调,当观察者中的数据有变化时会回调该方法
    27. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    28. if ([keyPath isEqualToString:@"content"]){
    29. self.textField.text = self.subVC.content;
    30. }
    31. }
    32. @end
  2. 子页面在返回主页面时修改对应属性的内容,则会回调主页面的回调方法
    1. - (void) btnClicked:(UIButton *)btn {
    2. self.content = @"子页面回传数据";//修改属性的内容
    3. [self.navigationController popViewControllerAnimated:YES];
    4. }

     

 

原文链接:http://www.cnblogs.com/mukekeheart/p/10448964.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号