iOS页面间传值的一些方式总结
2016-07-18 17:00
465 查看
废话不多说,直接进入主题:
这里要说的方式有6种:1、属性传值 2、block 3、delegate 4、UserDefault 5、单例 6、通知(篇幅原因我只写核心代码,如果看不懂可以直接在最下面去github 看demo)
下面上代码:
下面是第一个VC代码:
secondVc的代码:
Vc代码:
这里只有存和取两个动作:
和之前不同的是,这种方式只要进入这个界面就会取值,而不一定只是从上一个界面返回才传值。
这里我定义了一个单例类,用它存用户登录状态的信息,之后是控制器中的使用:
发通知:
收通知:
OK,就是这些了,虽然这些方式都能用于控制器之间传值,但是其实有些方式是没有必要用在我举例的这种普通场景(跑一下我的demo就明白这是什么场景了)下的(当然属性传值只能用于顺传),在我所举例的这种场景下,用block是最简洁的,delegate也可以,但是个人感觉对于传值来说过于麻烦了,通知也还可以,但还是不如block。但是单例和UserDefaults其实是不需要在这种场景下用的,他们可以用在两个控制器隔很远的情况下,或者两个控制器没有关联的情况下。就像我举的单例的例子中,存一下全局都可能用到的如用户信息,这样全局都能随时取得这个信息。
下面是demo:
my github:https://github.com/alan12138/somethingInteresting
这里要说的方式有6种:1、属性传值 2、block 3、delegate 4、UserDefault 5、单例 6、通知(篇幅原因我只写核心代码,如果看不懂可以直接在最下面去github 看demo)
1、block(个人觉得最常用的场景下最好用的)
先说我最常用的block吧,属性传值就很简单了,主要用于顺传,我们在这里包括下面都主要讲逆传。属性传值放在block里一起写了。下面上代码:
//secondVc.h typedef void (^TestBlock) (NSString *str); @interface ATNextViewController : UIViewController //定义block @property (nonatomic, copy) TestBlock testBlock; @end
//secondVc.m - (void)btnClick:(UIButton *)btn { if(self.testBlock) { //block传值 self.testBlock(@"绿色"); } [self.navigationController popViewControllerAnimated:YES]; }
下面是第一个VC代码:
//Vc.m - (void)btnClick:(UIButton *)btn { ATNextViewController *nextVc = [[ATNextViewController alloc] init]; nextVc.inStr = @"红色"; //属性传值,用于顺传,直接传就好了 //这里是block回传的值 nextVc.testBlock = ^(NSString *str) { NSLog(@"%@",str); }; [self.navigationController pushViewController:nextVc animated:YES]; }
2、delegate
代理要首先搞清楚谁传值给谁,我这里主要写的都是逆传,内层控制器传向外层控制器,那也就是secondVc传值给Vc,所以应该是Vc作为secondVc的代理,在代理方法接收secondVc传过来的值。secondVc的代码:
//secondVc.h //声明代理 @protocol ATNextVcDelegate <NSObject> @optional - (void)inStr:(NSString *)inStr; @end @interface ATNextViewController : UIViewController @property (nonatomic, weak) id<ATNextVcDelegate> delegate; @end
//secondVc.m //代理传值 - (void)btnClick:(UIButton *)btn { if ([self.delegate respondsToSelector:@selector(inStr:)]) { [self.delegate inStr:@"红色"]; } [self.navigationController popViewControllerAnimated:YES]; }
Vc代码:
//Vc.m //代理方法接收值 - (void)btnClick:(UIButton *)btn { ATNextViewController *nextVc = [[ATNextViewController alloc] init]; nextVc.delegate = self; [self.navigationController pushViewController:nextVc animated:YES]; } #pragma mark - ATNextVcDelegate - (void)inStr:(NSString *)inStr { NSLog(@"%@========", inStr); }
3、UserDefault
这种方式会在本地存下文件,属于数据持久化(关于数据持久化有时间会另开一篇详细讲解)的一种。再次打开程序依然会有上一次保存留下的值。这里只有存和取两个动作:
//secondVc.m - (void)btnClick:(UIButton *)btn { //存 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:@"黄色" forKey:@"btnColor"]; [defaults setObject:@"100x100" forKey:@"btnSize"]; [defaults synchronize]; [self.navigationController popViewControllerAnimated:YES]; }
//Vc.m - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //取 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *btnColor = [defaults objectForKey:@"btnColor"]; NSString *btnSize = [defaults objectForKey:@"btnSize"]; NSLog(@"%@ %@",btnColor,btnSize); }
和之前不同的是,这种方式只要进入这个界面就会取值,而不一定只是从上一个界面返回才传值。
4、单例
单例一般直接做成宏,用的时候拿过来直接用就好了,所以单例宏文件这里就不写了,感兴趣可以去demo看一下,直接上代码:这里我定义了一个单例类,用它存用户登录状态的信息,之后是控制器中的使用:
//ATLoginStatus.h #import <Foundation/Foundation.h> #import "ATSingleton.h" @interface ATLoginStatus : NSObject @property (nonatomic, assign) BOOL isLogin; @property (nonatomic, copy) NSString *phoneNumStr; SingletonH(LoginStatus) @end
// ATLoginStatus.m #import "ATLoginStatus.h" @implementation ATLoginStatus SingletonM(LoginStatus) @end
//secondVc.m - (void)btnClick:(UIButton *)btn { //存 ATLoginStatus *status = [ATLoginStatus sharedLoginStatus]; status.phoneNumStr = @"12345"; status.isLogin = YES; [self.navigationController popViewControllerAnimated:YES]; }
//Vc.m - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //取 ATLoginStatus *status = [ATLoginStatus sharedLoginStatus]; NSLog(@"%@ %d",status.phoneNumStr,status.isLogin); }
5、通知
通知主要是发通知和收通知两部:发通知:
//secondVc.m - (void)btnClick:(UIButton *)btn { //发出通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"btnColorNoti" object:self userInfo:@{@"btnColor": @"黄色"}]; [self.navigationController popViewControllerAnimated:NO]; }
收通知:
//Vc.m - (void)viewDidLoad { [super viewDidLoad]; //... //注册通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(btnColorNoti:) name:@"btnColorNoti" object:nil]; } //收到通知的时候调用这个方法接受到通知消息 - (void)btnColorNoti:(NSNotification *)noti { NSDictionary *dict = noti.userInfo; NSLog(@"%@",dict[@"btnColor"]); } //控制器销毁的时候注销通知监听 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
OK,就是这些了,虽然这些方式都能用于控制器之间传值,但是其实有些方式是没有必要用在我举例的这种普通场景(跑一下我的demo就明白这是什么场景了)下的(当然属性传值只能用于顺传),在我所举例的这种场景下,用block是最简洁的,delegate也可以,但是个人感觉对于传值来说过于麻烦了,通知也还可以,但还是不如block。但是单例和UserDefaults其实是不需要在这种场景下用的,他们可以用在两个控制器隔很远的情况下,或者两个控制器没有关联的情况下。就像我举的单例的例子中,存一下全局都可能用到的如用户信息,这样全局都能随时取得这个信息。
下面是demo:
my github:https://github.com/alan12138/somethingInteresting
相关文章推荐
- iOS开发极光推送显示 开发证书没有通过验证 是否重新上传证书?解决方法
- IOS中设置navigationItem的leftBarButtonItem或rightBarButtonItem与边界距离
- iOS开发——WebView加载HTML图片大小自适应与文章自动换行
- 【iOS开发】IMP指针的作用
- ios 正则表达式之验证手机号、邮箱、身份证、银行卡
- 学习笔记-斯坦福iOS7-第十三课:Core Data 和表格视图
- iOS 图片拉伸
- 学习笔记-斯坦福iOS7-第十二课:文档和Core Data
- ios根据内容设置cell的高度
- ios framework 真机和模拟器合并
- 学习笔记-斯坦福iOS7-第十一课:表格视图和iPad
- 新浪分享授权登录
- 学习笔记-斯坦福iOS7-第十课:多线程,滚动视图
- 学习笔记-斯坦福iOS7-第九课:动画,自动布局
- iOS 禁用第三方键盘
- 学习笔记-斯坦福iOS7-第八课:协议,block,动画
- iOS蓝牙开发(一)蓝牙相关基础知识
- iOS 通知中心传值
- iOS企业版IPA包分发说明
- 学习笔记-斯坦福iOS7-第七课:视图,绘制,手势识别