iOS开发中,页面传值是必不可少的。很多时候,控制器之间的传值是很常见。下面,我总结几种常见的页面传值方式,记录下来,方便以后查看。
准备两个控制器,第一个控制有一个UIButton和一个UILabel,第二个控制器有一个UITextField和一个UIButton。
以下的页面传值都围绕这两个控制器来演示。
代码如下:
#import "OneViewController.h"
#import "TwoViewController.h"
@interface OneViewController ()
/**显示文字的Label*/
@property(nonatomic,strong) UILabel *ZFLabel;
/**跳到第二个控制器的Button*/
@property(nonatomic,strong) UIButton *ZFBtn;
@end
@implementation OneViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupControls];
}
-(void)ZFBtnAction
{
TwoViewController *twoVC = [[TwoViewController alloc] init];
twoVC.str = @"我是属性传值";
[self presentViewController:twoVC animated:YES completion:^{
}];
}
-(void)setupControls
{
self.ZFLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 40)];
self.ZFLabel.backgroundColor = [UIColor cyanColor];
[self.view addSubview:self.ZFLabel];
self.ZFBtn = [UIButton buttonWithType:UIButtonTypeSystem];
self.ZFBtn.frame = CGRectMake(100, CGRectGetMaxY(self.ZFLabel.frame) + 10, 150, 30);
[self.ZFBtn setTitle:@"跳转到第二个控制器" forState:UIControlStateNormal];
[self.ZFBtn addTarget:self action:@selector(ZFBtnAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.ZFBtn];
}
@end
#import "TwoViewController.h"
@interface TwoViewController ()
/**输入框*/
@property(nonatomic,strong) UITextField *ZFTextField;
/**回到第一个控制器的Button*/
@property(nonatomic,strong) UIButton *ZFBtn;
@end
@implementation TwoViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupControls];
}
-(void)ZFBtnAction
{
[self dismissViewControllerAnimated:YES completion:^{
}];
}
-(void)setupControls
{
self.ZFTextField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 40)];
self.ZFTextField.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:self.ZFTextField];
self.ZFBtn = [UIButton buttonWithType:UIButtonTypeSystem];
self.ZFBtn.frame = CGRectMake(100, CGRectGetMaxY(self.ZFTextField.frame) + 10, 150, 30);
[self.ZFBtn setTitle:@"回到第一个控制器" forState:UIControlStateNormal];
[self.ZFBtn addTarget:self action:@selector(ZFBtnAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.ZFBtn];
}
@end
属性传值,顾名思义,在控制器里面定义一个属性,然后把值赋值给该控制器属性。属性传值,常用于正向传值,即一个控制器跳转到另一个控制器时候,把值传递给第二个控制器。
核心代码:
OneViewController控制器:
-(void)ZFBtnAction
{
TwoViewController *twoVC = [[TwoViewController alloc] init];
twoVC.str = @"我是属性传值";
[self presentViewController:twoVC animated:YES completion:^{
}];
}
TwoViewController控制器:
self.ZFTextField.text = self.str;
单例传值,就是创建一个单例对象,然后把值付给单例对象的属性。无论在哪个控制器,只要调用这个单例对象,就能获取单例对象属性的值。单例传值,可以用于正向、反向传值。
单例对象:
#import
@interface singleton : NSObject
@property(nonatomic,strong) NSString *str;
/**
获取单例对象
@return 当前对象
*/
+(singleton *)shareInstance;
@end
#import "singleton.h"
@implementation singleton
+(singleton *)shareInstance
{
static singleton *zfInstance;
if (!zfInstance) {
zfInstance = [[singleton alloc] init];
}
return zfInstance;
}
@end
OneViewController控制器:
-(void)ZFBtnAction
{
TwoViewController *twoVC = [[TwoViewController alloc] init];
singleton *zfInstance = [singleton shareInstance];
zfInstance.str = @"我是单例传值";
[self presentViewController:twoVC animated:YES completion:^{
}];
}
TwoViewController控制器:
singleton *zfInstance = [singleton shareInstance];
self.ZFTextField.text = zfInstance.str;
每个应用程序都有一个自己的沙盒,而NSUserDefaults就是存在于沙盒里面,系统已经为我们创建好了,我们只需要直接使用就好。NSUserDefaults可以用于正向、反向传值。
OneViewController控制器:
-(void)ZFBtnAction
{
TwoViewController *twoVC = [[TwoViewController alloc] init];
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:@"我是NSUserDefaults传值" forKey:@"ZFKey"];
[ud synchronize];
[self presentViewController:twoVC animated:YES completion:^{
}];
}
TwoViewController控制器:
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *str = [ud objectForKey:@"ZFKey"];
self.ZFTextField.text = str;
代理传值,是苹果开发中最经典的传值方式,常用语反向传值,即从一个控制器到另一个控制器,再由第二个控制器返回到第一个控制器,并且把值从第二个控制器传回到第一个控制器。代理传值比较麻烦,需要定义委托方、代理,而代理需要遵守协议。
OneViewController控制器:
@interface OneViewController ()
/**显示文字的Label*/
@property(nonatomic,strong) UILabel *ZFLabel;
/**跳到第二个控制器的Button*/
@property(nonatomic,strong) UIButton *ZFBtn;
@end
@implementation OneViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupControls];
}
-(void)ZFBtnAction
{
TwoViewController *twoVC = [[TwoViewController alloc] init];
twoVC.delegate = self;
[self presentViewController:twoVC animated:YES completion:^{
}];
}
-(void)transmitStr:(TwoViewController *)twoVC str:(NSString *)str
{
self.ZFLabel.text = str;
}
TwoViewController控制器:
#import
@class TwoViewController;
@protocol transmitValueDelegate<NSObject>
@optional
-(void)transmitStr:(TwoViewController *)twoVC str:(NSString *)str;
@end
@interface TwoViewController : UIViewController
@property(nonatomic,weak) id delegate;
@end
-(void)ZFBtnAction
{
if ([self.delegate respondsToSelector:@selector(transmitStr:str:)]) {
[self.delegate transmitStr:self str:@"我是代理传值"];
}
[self dismissViewControllerAnimated:YES completion:^{
}];
}
Block传值是苹果推荐的一种传值方式,和代理传值一样,常用语反向传值。Block传值写法比代理传值简单,也是比较流行的一种写法。
OneViewController控制器:
-(void)ZFBtnAction
{
TwoViewController *twoVC = [[TwoViewController alloc] init];
twoVC.ZFBlock = ^(NSString *str) {
self.ZFLabel.text = str;
};
[self presentViewController:twoVC animated:YES completion:^{
}];
}
TwoViewController控制器:
#import
@interface TwoViewController : UIViewController
@property(nonatomic,copy) void(^ZFBlock)(NSString *);
@end
-(void)ZFBtnAction
{
self.ZFBlock(@"我是block传值");
[self dismissViewControllerAnimated:YES completion:^{
}];
}
在苹果开发中,通知更是常见。我们用不但可以用通知进行传值,还能用通知给其他控制器发送其他信号、消息,比如键盘弹出消息等等。通知传值不但可以一对一,还可以一对多,多对多。
OneViewController控制器:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
[self setupControls];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMessage:) name:@"notiTransmitValue" object:nil];
}
-(void)receiveMessage:(NSNotification *)noti
{
self.ZFLabel.text = noti.userInfo[@"key"];
}
TwoViewController控制器:
-(void)ZFBtnAction
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"notiTransmitValue" object:nil userInfo:@{@"key":@"我是通知传值"}];
[self dismissViewControllerAnimated:YES completion:^{
}];
}