iOS开发之界面传值

学习了关于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传值尤其重要,需要根据自己的理解,多写多练才能熟练掌握。


加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值