你的位置:首页 > 操作系统

[操作系统]iOS页面间传值的一些方式总结


废话不多说,直接进入主题:

这里要说的方式有6种:1、属性传值 2、block 3、delegate 4、UserDefault 5、单例 6、通知(篇幅原因我只写核心代码,如果看不懂可以直接在最下面去github 看demo)

1、block(个人觉得最常用的场景下最好用的)

先说我最常用的block吧,属性传值就很简单了,主要用于顺传,我们在这里包括下面都主要讲逆传。属性传值放在block里一起写了。

下面上代码:

1 //secondVc.h2 typedef void (^TestBlock) (NSString *str);3 4 @interface ATNextViewController : UIViewController5 //定义block6 @property (nonatomic, copy) TestBlock testBlock;7 @end

1 //secondVc.m2 - (void)btnClick:(UIButton *)btn {3   if(self.testBlock) { //block传值4     self.testBlock(@"绿色");5   }6   7   [self.navigationController popViewControllerAnimated:YES];8 }

下面是第一个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的代码:

 1 //secondVc.h 2  3 //声明代理 4 @protocol ATNextVcDelegate <NSObject> 5  6 @optional 7 - (void)inStr:(NSString *)inStr; 8 @end 9 @interface ATNextViewController : UIViewController10 @property (nonatomic, weak) id<ATNextVcDelegate> delegate;11 @end

1 //secondVc.m2 //代理传值3 4 - (void)btnClick:(UIButton *)btn {5   if ([self.delegate respondsToSelector:@selector(inStr:)]) {6     [self.delegate inStr:@"红色"];7   }8   [self.navigationController popViewControllerAnimated:YES];9 }

 

Vc代码:

 1 //Vc.m 2 //代理方法接收值 3  4 - (void)btnClick:(UIButton *)btn { 5   ATNextViewController *nextVc = [[ATNextViewController alloc] init]; 6   nextVc.delegate = self; 7   [self.navigationController pushViewController:nextVc animated:YES]; 8 } 9 #pragma mark - ATNextVcDelegate10 - (void)inStr:(NSString *)inStr {11   NSLog(@"%@========", inStr);12 }

 

3、UserDefault

这种方式会在本地存下文件,属于数据持久化(关于数据持久化有时间会另开一篇详细讲解)的一种。再次打开程序依然会有上一次保存留下的值。

这里只有存和取两个动作:

 1 //secondVc.m 2 - (void)btnClick:(UIButton *)btn { 3   //存 4   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 5   [defaults setObject:@"黄色" forKey:@"btnColor"]; 6   [defaults setObject:@"100x100" forKey:@"btnSize"]; 7   [defaults synchronize]; 8  9   [self.navigationController popViewControllerAnimated:YES];10   11 }

 1 //Vc.m 2  3 - (void)viewWillAppear:(BOOL)animated { 4   [super viewWillAppear:animated]; 5   //取 6   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 7   NSString *btnColor = [defaults objectForKey:@"btnColor"]; 8   NSString *btnSize = [defaults objectForKey:@"btnSize"]; 9   NSLog(@"%@ %@",btnColor,btnSize);10 }

和之前不同的是,这种方式只要进入这个界面就会取值,而不一定只是从上一个界面返回才传值。

 

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 ATLoginStatusSingletonM(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、通知

通知主要是发通知和收通知两部:

发通知:

1 //secondVc.m2 3 - (void)btnClick:(UIButton *)btn {4   //发出通知5   [[NSNotificationCenter defaultCenter] postNotificationName:@"btnColorNoti" object:self userInfo:@{@"btnColor": @"黄色"}];6   [self.navigationController popViewControllerAnimated:NO];7 }

收通知:

//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