iOS实现页面间传值的方式:
delegate
方式notification
方式block
方式UserDefaults
或者文件方式SharedApplication
,定义一个变量来传递本篇教程中,有两个视图控制器,分别为ViewController
和AnotherController
,我们想把ViewController
中UITextField
的值传给AnotherController
中的UILabel
。
一.通过设置属性,实现页面间传值(适合单向传值)
ViewController.m
中的代码
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
AnotherController* another=[[AnotherController alloc] init];
another.value=self.valueText.text;
[self presentViewController:another animated:YES completion:nil];
}
AnotherController.h的代码
@property(nonatomic,strong)NSString* value;
AnotherController.m的代码
-(void)viewWillAppear:(BOOL)animated{
self.valueLabel.text=self.value;
}
运行图示:
总结:这一方式是通过在控制器中设置属性来接收传过来的值,不足就是设置的属性要暴露出来。
二.委托delegate
方式(两个页面双向传值)
使用委托模式(在两个类之间)是可以远程传值的,
AnotherController.h代码
@protocol AnotherDelegate <NSObject>
-(void)passValue:(NSString*) value;
@end
@interface AnotherController : UIViewController
@property(nonatomic,weak)id delegate;
@end
AnotherController.m代码
@interface AnotherController ()
@property(nonatomic,weak)UITextField* valueText;
@end
@implementation AnotherController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor greenColor];
UITextField* valueText=[[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 40)];
[self.view addSubview:valueText];
self.valueText=valueText;
self.valueText.backgroundColor=[UIColor whiteColor];
UIButton* btn=[[UIButton alloc] init];
btn.frame=CGRectMake(100, 240, 200, 40);
btn.backgroundColor=[UIColor redColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(sendDelegate) forControlEvents:UIControlEventTouchUpInside];
}
-(void)sendDelegate{
if ([self.delegate respondsToSelector:@selector(passValue:)]) {
[self.delegate passValue:self.valueText.text];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
ViewController.m代码:
@interface ViewController ()<AnotherDelegate>
@property(nonatomic,weak)UILabel* valueLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor orangeColor];
UILabel* valueLabel=[[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 20)];
[self.view addSubview:valueLabel];
self.valueLabel=valueLabel;
self.valueLabel.backgroundColor=[UIColor purpleColor];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
AnotherController* another=[[AnotherController alloc] init];
another.delegate=self;
[self presentViewController:another animated:YES completion:nil];
}
-(void)passValue:(NSString *)value{
self.valueLabel.text=value;
}
运行效果如图:
开启应用时效果图如下:
跳转到第二个界面,用来获取值:
返回第一个界面,利用协议中的方法来接收到从第二个界面传递过来的值:
注意:
第一个界面接收第二个界面传递过来的值,是通过以下的代理方法来实现的:
-(void)passValue:(NSString *)value{
self.valueLabel.text=value;
}
也就是在第二个界面中远程调用该方法,警记:此时的self.valueLabel
是不为nil
的,因为在进入第二个界面之前,我们已经完成了对第一个界面的初始化了,所以此时self.valueLabel
是存在的。
如果调用远程方法时,远程方法体中用到的控件还没有初始化,值为nil
。
三.通过通知notification
的方式实现
在AnotherController.m代码中,点击按钮发送通知且切换到第一个界面:
[btn addTarget:self action:@selector(passValue) forControlEvents:UIControlEventTouchUpInside];
-(void)passValue{
[[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeNameNotification" object:self userInfo:@{@"name":self.valueText.text}];
[self dismissViewControllerAnimated:YES completion:nil];
}
在ViewController.m代码中注册通知,并且在接收到通知时,调用指定方法:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ChangeNameNotification:) name:@"ChangeNameNotification" object:nil];
-(void)ChangeNameNotification:(NSNotification*)notification{
NSDictionary *nameDictionary = [notification userInfo];
self.valueLabel.text = [nameDictionary objectForKey:@"name"];
}
四.通过block方式实现
在AnotherController.h
中的代码:
#import
typedef void (^ablock)(NSString* str);//定义一个代码块变量类型
@interface AnotherController : UIViewController
@property(nonatomic,copy)ablock block;//定义一个代码块变量
@end
在AnotherController.m
中的代码:
-(void)passValue{
self.block(self.valueText.text);
[self dismissViewControllerAnimated:YES completion:nil];
}
在ViewController.m
中的代码:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
AnotherController* another=[[AnotherController alloc] init];
another.block=^(NSString* value){
self.valueLabel.text=value;
};
[self presentViewController:another animated:YES completion:nil];
}