该要: 页面间的传值一共分为六种方式。 属性传值, 单例传值, NSUserDefaults传值, 代理传值, block传值, 通知传值
完整的代码地址
属性传值
最简单的传值方式,正向传递。
在第二个页面 中定义一个属性,在第一个页面中赋值。并在第二个页面中取出来使用。
单例传值
很灵活,可以双向传递。(写入内存读取)
需要定义一个静态单例,第一个页面赋值给静态对象,第二个页面从其中取值。
NSUserDefaults传值
可以双向传递。(写入沙盒文件读取)
利用 NSUserDefaults类 将数据存储起来,在第二个页面中读取。
代理传值 (最经典)
多用于反向传递
在第二个页面中定义一个协议,并调用。让第一个页面也遵守这个协议,并实现传递数据的方法。
block传值(最流行,官方最推荐)
多用于反向传递
在第二个页面中定义一个block,并调用。并且在第一个页面中实现。
通知传值
多用于反向传值。
第一个页面监听 消息中心,第二个页面发送消息给消息中心。
SecondviewController *secondViewController = [[SecondviewController alloc] init];
//属性传值
secondViewController.str = @"属性传递的值"; //传递
[self presentViewController:secondViewController animated:YES completion:nil];
页面二中接收属性
@implementation SecondviewController
- (UITextField *)textField {
if(!_textField) {
_textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 40)];
_textField.textColor = [UIColor blackColor];
_textField.backgroundColor = [UIColor whiteColor];
_textField.borderStyle = UITextBorderStyleLine;
// 属性传值 -- 接收并显示
_textField.text = self.str;
}
return _textField;
}
#import
NS_ASSUME_NONNULL_BEGIN
@interface DefaultInstance : NSObject
@property(nonatomic, strong) NSString *str;
+(instancetype) sharedInstance;
@end
NS_ASSUME_NONNULL_END
DefaultInstance.m
#import "DefaultInstance.h"
@implementation DefaultInstance
//单例对象
+ (instancetype) sharedInstance {
static DefaultInstance *sharedVC = nil;
if(sharedVC == nil) {
sharedVC = [[DefaultInstance alloc] init];
}
return sharedVC;
}
@end
第一个页面中给单例赋值
SecondviewController *secondViewController = [[SecondviewController alloc] init];
//属性传值
// secondViewController.str = @"属性传递的值"; //传递
[DefaultInstance sharedInstance].str = @"单例传值"; // 从页面一 给单例对象赋值
[self presentViewController:secondViewController animated:YES completion:nil];
第二个页面取出相应的值
@implementation SecondviewController
- (UITextField *)textField {
if(!_textField) {
_textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 200, 40)];
_textField.textColor = [UIColor blackColor];
_textField.backgroundColor = [UIColor whiteColor];
_textField.borderStyle = UITextBorderStyleLine;
// 属性传值 -- 接收并显示
// _textField.text = self.str;
//单例传值 -- 接收 显示
_textField.text = [DefaultInstance sharedInstance].str;
//nsuserdefault传值
// _textField.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaults"];
}
return _textField;
}
NSUserDefaults传值 (可以双向传递)
第一个页面 赋值:
//NSUserDefaults传值
[[NSUserDefaults standardUserDefaults] setObject:@"NSUserDefaults传值" forKey:@"NSUserDefaults"];
[[NSUserDefaults standardUserDefaults] synchronize];
第二个页面取值:
//nsuserdefault传值
_textField.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaults"];
//委托方创建一个协议
@protocol passValueDelegate <NSObject>
// 定义一个传值的方法
- (void)passValue: (NSString *) str;
@end
在第二个页面中调用
//代理传值 -- 反向
[self.delegate passValue:self.textField.text];
让第一个页面遵守这个协议:
@interface ViewController () <passValueDelegate> //遵守协议
@property(nonatomic, strong)UILabel *label;
@property(nonatomic,strong) UIButton *btn;
@end
......
//代理传值实现协议方法,接收来自页面2 的值
- (void)passValue:(NSString *)str{
self.label.text = str;
}
//定义一个block进行页面反向传值
@property(copy) void(^block) (NSString *);
并在第二个页面中调用这个block传递相应 的值
//block传值 =
self.block(_textField.text);
在第一个页面中 实现这个block
//btn点击事件,跳转到页面2
- (void)btnClick{
SecondviewController *secondViewController = [[SecondviewController alloc] init];
//block传值,接收来自页面二的值
secondViewController.block = ^(NSString *str){
self.label.text = str;
};
[self presentViewController:secondViewController animated:YES completion:nil];
}
通知传值
在第一个页面中监听消息中心
// 添加监听,等待页面2 的传值
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notHandle:) name:@"notify" object:nil];
......
//接收到通知之后的处理。 参数1-- 通知
- (void) notHandle: (NSNotification *) not{
self.label.text = not.userInfo[@"not"];
}
在第二个页面中发送消息
//通知传值 --- 发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"notify" object: nil userInfo: @{@"not": self.textField.text}];
[self dismissViewControllerAnimated:YES completion:nil];