iOS七种传值总结(关键代码)
ViewController = 启动后的主界面
ZQMainVC = 主界面中的二级界面
ZQResignVC = 主界面中的二级界面
一、初始化传值:适用上一级界面往下一级界面传值 ViewController-> ZQMainVC
=============ZQMainVC类============
//写个类似构造函数的方法
@implementationZQMainVC
-(id)initWithUserName:(NSString*)userName WithPassWord:(NSString *)passWord {
self = [super init];
if (self) {
_passWord=passWord;
_userName=userName;
}
return self;
}
=============ViewController类=============
//调用传值处
ZQMainVC *mainVC=[[ZQMainVC alloc]initWithUserName:_userNameText.textWithPassWord:_passWordText.text];
[self.navigationController pushViewController:mainVC animated:YES];
二、属性传值:只适用于上级界面对下一级界面的跳转赋值 ViewController-> ZQMainVC和初始化传值比较,代码可读性低
=============ViewController类=============
ZQMainVC *mainVC=[[ZQMainVC alloc]init];
//直接对属性赋值,
mainVC.userName=_userNameText.text;
mainVC.passWord=_passWordText.text;
[self.navigationController pushViewController:mainVC animated:YES];
三、代理传值:适合下一级界面回传值给上一级 ZQResignVC-> ViewController
=============ZQResignVC类=============
//写代理方法
@protocolZQResignVCDelegate <NSObject>
-(void)sendMessage:(NSString*)userName withPassword:(NSString *)password;
@end
//定义属性
@property(nonatomic,assign)id<ZQResignVCDelegate>delegate;
//调用处
-(void)buttonClick:(UIButton*)button{
if (self.delegate&&[self.delegaterespondsToSelector:@selector(sendMessage:withPassword:)]) {
[self.delegate sendMessage:_userNameText.textwithPassword:_passWordText.text];
}
[self.navigationController popToRootViewControllerAnimated: YES];
}
=============ViewController类=============
ZQResignVC *resignVC=[[ZQResignVC alloc]init];
// 设置代理
resignVC.delegate=self;
[self.navigationController pushViewController:resignVC animated:YES];
四、单例传值:对没有跳转关系的两个controller进行传值(有拿Appdelegate当单例的用法,一个意思,区别在于Appdelegate中一大堆的属性。。。乱)
============= ZQShareManager=============
@interface ZQShareManager : NSObject
@property (copy, nonatomic) NSString *userName;
@property (copy, nonatomic) NSString *password;
// 申明一个类方法
+ (ZQShareManager *)shareUserInfo;
@end
@implementation ZQShareManager
+ (ZQShareManager *)shareUserInfo{
static ZQShareManager *shareManager = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
shareManager = [[self alloc] init];
});
return shareManager;
}
@end
// 怎么用就不写了,在想保存的地方对ZQShareManager的属性赋值,在想用的地方调用ZQShareManager中的属性
五、NSuserDefault传值:对没有跳转关系的两个controller进行传值(类似弄个sqlite数据库传值了,或写个文件传值,区别单例在于,应用被kill后再次启动还有值,而上面的单例重启应用后,就木有值了)
=============ViewController类=============
-(void)buttonClick:(UIButton *)button{
// 赋值保存
[[NSUserDefaults standardUserDefaults]setValue:_userNameText.text forKey:@"UserId"];
[[NSUserDefaults standardUserDefaults]setValue:_passWordText.text forKey:@"PassWord"];
// 写入NSUserDefaults
[[NSUserDefaults standardUserDefaults]synchronize];
ZQMainVC *mainVC=[[ZQMainVC alloc]init];
[self.navigationController pushViewController:mainVC animated:YES];
}
=============ZQMainVC类============
// 需要用到的地方取出NSUserDefaults中的值
self.userName=[[NSUserDefaults standardUserDefaults]objectForKey:@"UserId"];
self.passWord=[[NSUserDefaults standardUserDefaults]objectForKey:@"PassWord"];
六、通知传值:对没有跳转关系的两个controller进行传值,这个要用的话一定要谨慎,主要用在线程中,比如下载东西,你都不知道什么时候会触发下载完的时候,才考虑用发通知的方式,这东西用多了,代码可读性变得非常差
=============ZQResignVC类=============
// 点击按钮发送通知
-(void)buttonClick:(UIButton *)button{
[self textResignFirstResponder];
/***************通知传值****************/
NSArray *array=[[NSArray alloc]initWithObjects:_userNameText.text,_passWordText.text, nil];
//发送通知 sendMessage表示通知详情 array表示传输数据
[[NSNotificationCenter defaultCenter] postNotificationName:@"ZQSendMessage" object:array];
/*****************通知传值****************/
[self.navigationController popToRootViewControllerAnimated: YES];
}
============= ViewController =============
//-viewDidLoad方法中注册接受通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getZQMessage:) name:@"ZQSendMessage" object:nil];
//解析通知中的数据赋值
-(void)getZQMessage:(NSNotification *)notification{
NSArray *array=[[NSArray alloc]initWithArray:notification.object];
_userNameText.text=array[0];
_passWordText.text=array[1];
}
// 记得界面如果界面销毁移除掉通知监听
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
七、block传值:适用于子界面中的点击事件回传,比在子界面写一大堆delegeta要看着方便,用于子线程回调也OK
=============RedView=============
@class RedView;
typedef void(^TouchButton)(RedView *);
@interface RedView : UIView
@property(nonatomic,copy)TouchButton block;
@property(nonatomic,retain) NSString *title;
@end
@interface RedView()
{
UIButton *button;
}
@end
@implementation RedView
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
button = [UIButton buttonWithType:UIButtonTypeSystem];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
button.frame = frame;
button.backgroundColor = [UIColor redColor];
[self addSubview:button];
}
return self;
}
-(void)buttonClick:(id)sender{
NSLog(@"点击");
_title = @"装请带上我飞";
_block(self);
}
@end
=============ViewController=============
RedView *rView = [[RedView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
rView.block = ^(RedView *button){
// 注意block的循环引用问题
title.text = button.title;
};
ViewController = 启动后的主界面
ZQMainVC = 主界面中的二级界面
ZQResignVC = 主界面中的二级界面
ZQShareManager = 单例的类
RedView = ViewController的子View
一、初始化传值:适用上一级界面往下一级界面传值 ViewController-> ZQMainVC
=============ZQMainVC类============
//写个类似构造函数的方法
@implementationZQMainVC
-(id)initWithUserName:(NSString*)userName WithPassWord:(NSString *)passWord {
self = [super init];
if (self) {
_passWord=passWord;
_userName=userName;
}
return self;
}
=============ViewController类=============
//调用传值处
ZQMainVC *mainVC=[[ZQMainVC alloc]initWithUserName:_userNameText.textWithPassWord:_passWordText.text];
[self.navigationController pushViewController:mainVC animated:YES];
二、属性传值:只适用于上级界面对下一级界面的跳转赋值 ViewController-> ZQMainVC和初始化传值比较,代码可读性低
=============ViewController类=============
ZQMainVC *mainVC=[[ZQMainVC alloc]init];
//直接对属性赋值,
mainVC.userName=_userNameText.text;
mainVC.passWord=_passWordText.text;
[self.navigationController pushViewController:mainVC animated:YES];
三、代理传值:适合下一级界面回传值给上一级 ZQResignVC-> ViewController
=============ZQResignVC类=============
//写代理方法
@protocolZQResignVCDelegate <NSObject>
-(void)sendMessage:(NSString*)userName withPassword:(NSString *)password;
@end
//定义属性
@property(nonatomic,assign)id<ZQResignVCDelegate>delegate;
//调用处
-(void)buttonClick:(UIButton*)button{
if (self.delegate&&[self.delegaterespondsToSelector:@selector(sendMessage:withPassword:)]) {
[self.delegate sendMessage:_userNameText.textwithPassword:_passWordText.text];
}
[self.navigationController popToRootViewControllerAnimated: YES];
}
=============ViewController类=============
ZQResignVC *resignVC=[[ZQResignVC alloc]init];
// 设置代理
resignVC.delegate=self;
[self.navigationController pushViewController:resignVC animated:YES];
四、单例传值:对没有跳转关系的两个controller进行传值(有拿Appdelegate当单例的用法,一个意思,区别在于Appdelegate中一大堆的属性。。。乱)
============= ZQShareManager=============
@interface ZQShareManager : NSObject
@property (copy, nonatomic) NSString *userName;
@property (copy, nonatomic) NSString *password;
// 申明一个类方法
+ (ZQShareManager *)shareUserInfo;
@end
@implementation ZQShareManager
+ (ZQShareManager *)shareUserInfo{
static ZQShareManager *shareManager = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
shareManager = [[self alloc] init];
});
return shareManager;
}
@end
// 怎么用就不写了,在想保存的地方对ZQShareManager的属性赋值,在想用的地方调用ZQShareManager中的属性
五、NSuserDefault传值:对没有跳转关系的两个controller进行传值(类似弄个sqlite数据库传值了,或写个文件传值,区别单例在于,应用被kill后再次启动还有值,而上面的单例重启应用后,就木有值了)
=============ViewController类=============
-(void)buttonClick:(UIButton *)button{
// 赋值保存
[[NSUserDefaults standardUserDefaults]setValue:_userNameText.text forKey:@"UserId"];
[[NSUserDefaults standardUserDefaults]setValue:_passWordText.text forKey:@"PassWord"];
// 写入NSUserDefaults
[[NSUserDefaults standardUserDefaults]synchronize];
ZQMainVC *mainVC=[[ZQMainVC alloc]init];
[self.navigationController pushViewController:mainVC animated:YES];
}
=============ZQMainVC类============
// 需要用到的地方取出NSUserDefaults中的值
self.userName=[[NSUserDefaults standardUserDefaults]objectForKey:@"UserId"];
self.passWord=[[NSUserDefaults standardUserDefaults]objectForKey:@"PassWord"];
六、通知传值:对没有跳转关系的两个controller进行传值,这个要用的话一定要谨慎,主要用在线程中,比如下载东西,你都不知道什么时候会触发下载完的时候,才考虑用发通知的方式,这东西用多了,代码可读性变得非常差
=============ZQResignVC类=============
// 点击按钮发送通知
-(void)buttonClick:(UIButton *)button{
[self textResignFirstResponder];
/***************通知传值****************/
NSArray *array=[[NSArray alloc]initWithObjects:_userNameText.text,_passWordText.text, nil];
//发送通知 sendMessage表示通知详情 array表示传输数据
[[NSNotificationCenter defaultCenter] postNotificationName:@"ZQSendMessage" object:array];
/*****************通知传值****************/
[self.navigationController popToRootViewControllerAnimated: YES];
}
============= ViewController =============
//-viewDidLoad方法中注册接受通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getZQMessage:) name:@"ZQSendMessage" object:nil];
//解析通知中的数据赋值
-(void)getZQMessage:(NSNotification *)notification{
NSArray *array=[[NSArray alloc]initWithArray:notification.object];
_userNameText.text=array[0];
_passWordText.text=array[1];
}
// 记得界面如果界面销毁移除掉通知监听
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
七、block传值:适用于子界面中的点击事件回传,比在子界面写一大堆delegeta要看着方便,用于子线程回调也OK
=============RedView=============
@class RedView;
typedef void(^TouchButton)(RedView *);
@interface RedView : UIView
@property(nonatomic,copy)TouchButton block;
@property(nonatomic,retain) NSString *title;
@end
@interface RedView()
{
UIButton *button;
}
@end
@implementation RedView
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
button = [UIButton buttonWithType:UIButtonTypeSystem];
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
button.frame = frame;
button.backgroundColor = [UIColor redColor];
[self addSubview:button];
}
return self;
}
-(void)buttonClick:(id)sender{
NSLog(@"点击");
_title = @"装请带上我飞";
_block(self);
}
@end
=============ViewController=============
RedView *rView = [[RedView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
rView.block = ^(RedView *button){
// 注意block的循环引用问题
title.text = button.title;
};