前面介绍了通过UINavigationController进行控制器跳转的知识。现在来讲解一下在控制器跳转过程中,需要做的一件很重要的操作—传递数据。
IOS开发中数据传递的方法有很多,最常见的为:
1)属性传值;
2)代理传值;
3)通知机制传值;
4)block传值;
还可以通过数据存储来进行传值。
1、 属性传值(顺传:从上一个控制器传给下一个控制器)
控制器跳转方向:first -> second;数据传递方向:first -> second
为了简单,使用storyboard,为了跳转使用导航栏管理控制器。首先创建两个控制器:HXFirstViewController、HXSecondViewController,从First中按钮拖线至Second,不需要判断,直接跳转。 但此刻需要传值,之前我们曾说过,利用拖线实现跳转的时候,控制器在跳转之前会执行 -(void)prepareForSegue: sender: 方法。由于是直接跳转,所以我们直接实现该方法就行。首先在HXFirstViewController中的UITextField属性,在HXSecondViewController.h文件中声明一个属性并拿到UILabel的属性。
在HXSecondViewController.h#import <UIKit/UIKit.h>
@interface HXSecondViewController : UIViewController
/**
* 接受First控制器传来的数据
*/
@property (nonatomic, strong) NSString *textFieldString;
@end
在HXFirstViewController.m文件中实现- (void)prepareForSegue: sender:方法:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// 获得目标控制器(HXSecondViewController)
HXSecondViewController *secondVC = segue.destinationViewController;
// 给目标控制器属性传值
secondVC.textFieldString = self.textField.text;
}
运行效果:
2、 代理传递(逆传:从下一个控制器传给上一个控制器)
控制器跳转方向:Three-> first;数据传递方向:Three-> first
代理是一种程序设计模式,在网络上有很多关于代理模式的资料,在这里我只是简单的说一下,让大家心里有代理的映象。
我常常拿请保姆的例子来理解代理:比如,某个家庭要照顾小孩,监理人不用亲自照顾,那么他就需要请一个保姆(代理)来照顾孩子。但是并不是每个人都会被这家人录用,想要做这家的保姆必须要符合、遵循这些条件(招聘条件),如:(1)年龄在30-40之间;(2)必须是女性…等等;这些招聘条件就对应代理中的协议方法。
总结:当一个对象A不想亲自执行某个操作时,可以通知它的代理B来完成这个操作;B要想成为A的代理,那么B必须遵守A的代理,并实现A的代理中的协议方法。
下面通过代理模式的数据传递来了解代理和如何利用代理实现数据传递:
上代码,接着上面的项目,新建一个控制器HXThreeViewController。
在各自的控制器中拿到各自UITextField的属性。在HXThreeViewController.h文件中代码如下:
#import <UIKit/UIKit.h>
@class HXThreeViewController;
@protocol HXThreeViewControllerDelegate <NSObject>
@optional
/**
* 协议方法
*/
- (void)viewController:(HXThreeViewController *)vc inputedValueString:(NSString *)textFiledString;
@end
@interface HXThreeViewController : UIViewController
/**
* 设置代理对象
*/
@property (nonatomic, weak) id<HXThreeViewControllerDelegate> delegate;
@end
HXThreeViewController.m文件中实现返回功能:
- (IBAction)clickBack:(id)sender {
// 将数据传给代理
// 1.判断Three代理有没有实现协议方法viewController:inputedValueString:
if ([self.delegate respondsToSelector:@selector(viewController:inputedValueString:)]) {
// 实现了协议方法,就调用代理实现的协议方法
[self.delegate viewController:self inputedValueString:self.textField.text];
}
// 弹出当前控制器
[self.navigationController popViewControllerAnimated:YES];
}
当从HXFirstViewController控制器跳转至HXThreeViewController控制器时,在HXFirstViewController.m中执行Segue跳转前的方法-(void)prepareForSegue: sender:,如下:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// 获得目标控制器(HXSecondViewController)
HXThreeViewController *threeVC = segue.destinationViewController;
//设置threeVC为当前控制器
threeVC.delegate = self;
}
#pragma mark HXThreeViewControllerDelegate
- (void)viewController:(HXThreeViewController *)vc inputedValueString:(NSString *)textFiledString {
self.textField.text = textFiledString;
}
运行效果:
数据传递的前两种方式已经介绍完了,对于代理方法大家要很重视才行,在开发中会经常用到。通知机制和block本文中先不做介绍。以后的文章会讲到。