测试导航测试导航测试导航
  1. 首页
  2. iOS开发
  3. iOS页面传值的几种方式

iOS页面传值的几种方式

这里要说的方式有6种:1、属性传值;2、block;3、delegate;4、UserDefault;5、单例;6、通知(篇幅原因我只写核心代码)。1、block(个人觉得最常用的场景下最好用的)先说...


这里要说的方式有6种:1、属性传值;2、block;3、delegate;4、UserDefault;5、单例;6、通知(篇幅原因我只写核心代码)。


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.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、通知[NSNotification]

notification.gif

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


发通知:


//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其实是不需要在这种场景下用的,他们可以用在两个控制器隔很远的情况下,或者两个控制器没有关联的情况下。就像我举的单例的例子中,存一下全局都可能用到的如用户信息,这样全局都能随时取得这个信息。


版权声明:本文来自【王杭个人博客】http://www.wanghang.win/
wanghang
相关推荐
发表评论
访客的头像

留言列表
  • 猪OK网  评论于  

    0.30

  • 评论者  评论于  

    内容不错,先慢慢研究。

    • wanghang  评论于  

      嗯嗯,欢迎您的支持哈

  • 小蚁  评论于  

    不错哦

    • wanghang  评论于  

      谢谢支持哈

  • 青梅历史网  评论于  

    好专业的样子,先收藏了

    • wanghang  评论于  

      欢迎来访哦

  • 森云  评论于  

    博主还会ios啊,全能啊

    • ffffff  评论于  

      ffff

    • wanghang  评论于  

      我的职业就是iOS开发啊 ,过奖啦

      • 森云  评论于  

        好吧,咱俩可以搭配了,我是java

        • wanghang  评论于  

          哈哈,技术好友啊,多多关照啦

          • 森云  评论于  

            搭配的哈哈

分享:

支付宝

微信