iOS开发之界面传值

来源:互联网 发布:纯净水能烧开喝吗 知乎 编辑:程序博客网 时间:2024/05/22 13:53

学习了关于iOS开发中界面传值的基本用法,记录下笔记。
学习阶段,如果哪部分有问题,欢迎指正,共同探讨。@Apach3


iOS中几种常见的传值方式:

(1)属性传值:正向传值,只能从a界面跳转到b传值。
(2)单例传值:将数据储存到内存,然后读内存达到传值目的,可以实现正向、反向、跨页面传值。
(3)NSUserDefaults传值:将数据储存到文件,然后读文件达到传值目的,可以实现正向、反向、跨页面传值。
(4)代理传值:委托方->delegate通讯->代理方,委托方->持有协议、调用协议方法->协议,协议->遵守协议、实现协议方法->代理方。
(5)block传值:不像代理那么麻烦,设置简单,苹果主推,和代理传值一样适用于反向传值,有直接跳转关系的传值。
(6)通知传值:使用灵活,适用于跨页面传值。先在接收方定义观察者,等待通知中心发出的消息,然后由发送方发送到通知中心,通知中心拿到数据再回调给接收方。


代码实现六种传值:

ViewController.m:

#import "ViewController.h"#import "NextViewController.h"#import "DefaultInstance.h"/* 代理传值 - 遵守协议 */@interface ViewController () <valueDelegate>@property (nonatomic, strong) UIButton *nextVCButton;@property (nonatomic, strong) UILabel *textLabel;@property (nonatomic, strong) UILabel *showLabel;@end@implementation ViewController- (UIButton *)nextVCButton {    if (!_nextVCButton) {        _nextVCButton = [UIButton buttonWithType:UIButtonTypeCustom];        [_nextVCButton setTitle:@"点击跳到下个页面传值" forState:UIControlStateNormal];        [_nextVCButton setFrame:CGRectMake((self.view.frame.size.width-200)/2, 200, 200, 30)];        [_nextVCButton setBackgroundColor:[UIColor grayColor]];        [_nextVCButton addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];    }    return _nextVCButton;}- (UILabel *)textLabel {    if (!_textLabel) {        _textLabel = [[UILabel alloc] initWithFrame:CGRectMake((self.view.frame.size.width-200)/2, 250, 200, 30)];        _textLabel.text = @"这是第一个页面";        _textLabel.backgroundColor = [UIColor redColor];        _textLabel.textColor = [UIColor whiteColor];        _textLabel.font = [UIFont boldSystemFontOfSize:25];        _textLabel.textAlignment = NSTextAlignmentCenter;    }    return _textLabel;}- (UILabel *)showLabel {    if (!_showLabel) {        _showLabel = [[UILabel alloc] initWithFrame:CGRectMake((self.view.frame.size.width-200)/2, 300, 200, 30)];        _showLabel.backgroundColor = [UIColor orangeColor];        _showLabel.textColor = [UIColor whiteColor];        _showLabel.font = [UIFont boldSystemFontOfSize:15];        _showLabel.textAlignment = NSTextAlignmentCenter;    }    return _showLabel;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    [self.view addSubview:self.nextVCButton];    [self.view addSubview:self.textLabel];    [self.view addSubview:self.showLabel];}- (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    /*     单例传值 - 反向接收     */    _showLabel.text = [DefaultInstance sharedInstance].string;    /*     NSUserDefaults传值 - 反向接收     */    _showLabel.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"fanxiang"];}- (void)buttonClick:(id)sender {    NextViewController *nextVC = [[NextViewController alloc] init];    /*     属性传值 - 传递     */    nextVC.string = @"属性传值 - 收到了";    /*     单例传值 - 传递     */    [DefaultInstance sharedInstance].string = @"单例传值 - 收到了";    /*     NSUserDefaults传值 - 传递     */    [[NSUserDefaults standardUserDefaults] setObject:@"NSUserDefaults传值" forKey:@"NSUserDefaults"];                              //写数据到文件    [[NSUserDefaults standardUserDefaults] synchronize];        //同步数据    /*     代理传值 - 设置代理关系     */    nextVC.delegate = self;    /*     block传值 - 实现block,接受数据     */    nextVC.block = ^(NSString *string) {        _showLabel.text = string;    };    /*     通知传值 - 添加监听,等待传值     */    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notifiHandle:) name:@"notifi" object:nil];    [self presentViewController:nextVC animated:YES completion:nil];}/* 代理传值 - 实现协议方法,接受来自页面的值 */- (void)passValue:(NSString *)string {    _showLabel.text = string;}/* 通知传值 - 接收到通知之后的处理 */- (void)notifiHandle:(NSNotification *)notifi {    _showLabel.text = notifi.userInfo[@"notifi"];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end

NextViewController.h:

#import <UIKit/UIKit.h>/* 代理传值 - 委托方创建一个协议 */@protocol valueDelegate <NSObject>- (void)passValue:(NSString *)string;@end@interface NextViewController : UIViewController@property (nonatomic, strong) UIButton *button;@property (nonatomic, strong) UILabel *textLabel;@property (nonatomic, strong) UILabel *showLabel;/* 属性传值 - 属性 */@property (nonatomic, strong) NSString *string;/* 代理传值 - 定义一个持有协议的id指针 *///@property (weak)id<valueDelegate>delegete;@property (nonatomic, weak) id<valueDelegate> delegate;/* block传值 - 定义(返回值类型(block名字)block参数) */@property (nonatomic, copy) void (^block)(NSString *);@end

NextViewController.m:

#import "NextViewController.h"#import "DefaultInstance.h"@interface NextViewController ()@end@implementation NextViewController- (UIButton *)button {    if (!_button) {        _button = [UIButton buttonWithType:UIButtonTypeCustom];        [_button setTitle:@"点击跳回上个页面传值" forState:UIControlStateNormal];        [_button setFrame:CGRectMake((self.view.frame.size.width-200)/2, 200, 200, 30)];        [_button setBackgroundColor:[UIColor grayColor]];        [_button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];    }    return _button;}- (UILabel *)textLabel {    if (!_textLabel) {        _textLabel = [[UILabel alloc] initWithFrame:CGRectMake((self.view.frame.size.width-200)/2, 250, 200, 30)];        _textLabel.text = @"这是第二个页面";        _textLabel.backgroundColor = [UIColor redColor];        _textLabel.textColor = [UIColor whiteColor];        _textLabel.font = [UIFont boldSystemFontOfSize:25];        _textLabel.textAlignment = NSTextAlignmentCenter;    }    return _textLabel;}- (UILabel *)showLabel {    if (!_showLabel) {        _showLabel = [[UILabel alloc] initWithFrame:CGRectMake((self.view.frame.size.width-200)/2, 300, 200, 30)];        _showLabel.backgroundColor = [UIColor orangeColor];        _showLabel.textColor = [UIColor whiteColor];        _showLabel.font = [UIFont boldSystemFontOfSize:15];        _showLabel.textAlignment = NSTextAlignmentCenter;    }    return _showLabel;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    self.view.backgroundColor = [UIColor whiteColor];    [self.view addSubview:self.button];    [self.view addSubview:self.textLabel];    [self.view addSubview:self.showLabel];}- (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    /*     属性传值 - 接收     */    _showLabel.text = _string;    /*     单例传值 - 接收     */    _showLabel.text = [DefaultInstance sharedInstance].string;    /*     NSUserDefaults传值 - 接收     */    _showLabel.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"NSUserDefaults"];}- (void)buttonClick:(id)sender {    /*     单例传值 - 反向传递     */    [DefaultInstance sharedInstance].string = @"单例传值 - 反向传递 - 收到了";    /*     NSUserDefaults传值 - 反向传递     */    [[NSUserDefaults standardUserDefaults] setObject:@"NSUserDefaults反向传值" forKey:@"fanxiang"];    [[NSUserDefaults standardUserDefaults] synchronize];    /*     代理传值 - 反向传递     */    [self.delegate passValue:@"代理传值 - 收到了"];    /*     block传值 - 反向传递     */    self.block(@"block传值 - 收到了");    /*     通知传值 - 发送通知     */    [[NSNotificationCenter defaultCenter] postNotificationName:@"notifi" object:nil userInfo:@{@"notifi":@"通知传值 - 收到了"}];    [self dismissViewControllerAnimated:YES completion:nil];}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}

DefaultInstance.h:

#import <Foundation/Foundation.h>@interface DefaultInstance : NSObject@property (nonatomic, strong) NSString *string;+ (instancetype)sharedInstance;@end

DefaultInstance.m:

/* 单例类 */#import "DefaultInstance.h"@implementation DefaultInstance/* 使用静态变量通过类方法创建单例对象 */+ (instancetype)sharedInstance {    static DefaultInstance *sharedVC = nil;    if (sharedVC == nil) {        sharedVC = [[DefaultInstance alloc] init];    }    return sharedVC;}@end

模拟器图片:

图片为NSUserDefaults传值的截图。
模拟器图片
模拟器图片1


总结:

各个传值方式应用不同的场景,各有各的优缺点。代理传值和block传值尤其重要,需要根据自己的理解,多写多练才能熟练掌握。


加油!

原创粉丝点击