博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS页面间传值的六种方式
阅读量:5112 次
发布时间:2019-06-13

本文共 4275 字,大约阅读时间需要 14 分钟。

一般ios页面间的传值方式分为6种:1、属性传值;2、block;3、delegate;4、UserDefault;5、单例;6、通知。

 

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

转载于:https://www.cnblogs.com/akiha/p/5744791.html

你可能感兴趣的文章
Minimum Inversion Number 【线段数】
查看>>
从日常生活中看对象
查看>>
近期博客内容的规划(关于Swift语言)
查看>>
守护线程
查看>>
HTML5学习笔记<二>:元素,属性,格式化
查看>>
c#职责链模式
查看>>
妙趣横生的算法--二叉树
查看>>
策略模式(Strategy Pattern)
查看>>
Android系统兼容性问题(持续更新)
查看>>
获取用户位置
查看>>
Spring入门(一)
查看>>
Ubuntu 13.04设置root用户登录图形界面
查看>>
HTML5开发 Local Storage 本地存储
查看>>
第19届Jolt大奖揭晓
查看>>
UWP学习记录8-设计和UI之控件和模式5
查看>>
MySQL 索引 总结
查看>>
VMware client 无法显示hardware中的信息,提示No new host data available. Data will be updated in 5 minutes....
查看>>
qt学习之路
查看>>
前端动态属性页面的 要用id做name 因为这样方便在提交表单时候取到值
查看>>
高并发唯一ID解决方案
查看>>