zoukankan      html  css  js  c++  java
  • iOS页面间传值的一些方式总结

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

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

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

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

    下面上代码:

    1 //secondVc.h
    2 typedef void (^TestBlock) (NSString *str);
    3 
    4 @interface ATNextViewController : UIViewController
    5 //定义block
    6 @property (nonatomic, copy) TestBlock testBlock;
    7 @end
    1 //secondVc.m
    2 - (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 : UIViewController
    10 @property (nonatomic, weak) id<ATNextVcDelegate> delegate;
    11 @end
    1 //secondVc.m
    2 //代理传值
    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 - ATNextVcDelegate
    10 - (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 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、通知

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

    发通知:

    1 //secondVc.m
    2 
    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

  • 相关阅读:
    pyqt5 动画学习(二) 改变控件颜色
    pyqt5 QGraphicsView颜色动画问题(不兼容,运行不了动画)
    selenium chrome浏览器与chrome.driver的对应关系
    使用tkinter加载png,jpg
    SVN是什么,svn的目录结构
    性能测试中用LambdaProbe监控Tomcat Tomcat和Probe的配置
    Mysql从客户端连接服务器连不上的问题
    已达到计算机的连接数最大值,无法再同此远程计算机连接”的解决办法
    解决远程桌面无法连接的问题
    查看端口是否被打开、占用、开放的有关命令。
  • 原文地址:https://www.cnblogs.com/alan12138/p/5681921.html
Copyright © 2011-2022 走看看