UI_界面传值方式

引言

在iOS开发过程中,界面传值无处不在,可以说界面传值在iOS开发过程中是非常重要的,而传值方式也多种多样,如下我将介绍几种常见的界面传值方式。

  • 现在模拟传递用户名:userName。

属性传值

属性传值一般用于从上一个视图控制器传值到下一个视图控制器,即从主页传值到详情页。

  • 传值步骤:

steps 1:在DetailViewController.h文件中将需要获取的值声明成属性。

#import <UIKit/UIKit.h>  

@interface DetailViewController : UIViewController  

@property (nonatomic, strong)NSString *userName; /**< 用户名 */  

@end  

steps 2:在HomeViewController.m文件中导入头文件“DetailViewController.h”,然后在界面跳转逻辑处理方法中初始化DetailViewController,并通过点语法给属性userName赋值需要传递的值。

- (void)respondsToButton:(UIButton *)sender {  

    // 初始化详情视图控制器  
    DetailViewController *detailVc = [[DetailViewController alloc] init];  

    // 属性传值:赋值  
    detailVc.userName = @"admin";  

    // 模态切换(界面跳转)  
    [self presentViewController:detailVc animated:YES completion:nil];  

}  

steps 3:在DetailViewController.m文件viewDidLoad方法中获取userName的值,此时获取到的值就是从主页传过来的值。

- (void)viewDidLoad {  
    [super viewDidLoad];  

    // 获取打印userName的值  
    NSLog(@"userName is ‘%@’.", self.userName); // 输出"userName is ‘admin’."  

}  

init传值

init方法传值与属性传值类似,一般用于从上一个视图控制器传值到下一个视图控制器,即从主页传值到详情页。

  • 传值步骤:

steps 1:在DetailViewController.h文件中声明init方法。

- (instancetype)initWithUserName:(NSString *)userName; /* init传值方法声明 */  

steps 2:在HomeViewController.m文件中导入头文件“DetailViewController.h”,然后在界面跳转逻辑处理方法中通过initWithUserName:方法初始化DetailViewController并赋值。

(void)respondsToButton:(UIButton *)sender {  

    // 初始化详情视图控制器  
    DetailViewController *detailVc = [[DetailViewController alloc] initWithUserName:@"admin"];  

    // 模态切换(界面跳转)  
    [self presentViewController:detailVc animated:YES completion:nil];  

}  

steps 3:在DetailViewController.m文件中重写init方法,即实现initWithUserName方法,在这个方法中获取userName的值,此时获取到的值就是从主页传过来的值。

- (instancetype)initWithUserName:(NSString *)userName {  
    if (self = [super init]) {  

        // 获取打印userName的值  
        NSLog(@"userName is ‘%@’.", userName); // 输出"userName is ‘admin’."  

    }  
    return self;  
}  

通知传值

通知传值适用于任意控制器(界面),不管两个控制器之间是否有关联,只需满足一个条件,在传值的时候必须保证通知已经被设定,即已添加通知(观察者observer)。

现假设从详情界面传值到主界面,即从下一个界面传值到上一个界面,具体实现方式如下。

  • 传值步骤:

steps 1:注册通知:为保证在传值时通知已经被设定,因此需要在HomeViewController.m文件中注册通知。

#import "HomeViewController.h"  
#import "DetailViewController.h"  

@interface HomeViewController ()  

- (void)registeredNotification; /**< 注册通知 */  

@end  

@implementation HomeViewController  

- (void)viewDidLoad {  
    [super viewDidLoad];  
    [self registeredNotification];  
}  

#pragma mark - registerd notification  
- (void)registeredNotification {  

    /** 
     *  注册通知 
     * 
     *  @param observer 观察者对象 
     *  @param selector 触发方法,即当收到通知之后执行的方法 
     *  @param name     通知代号,即通知标识,发送通知时的标识必须和注册通知时的标识一致 
     *  @param object   是否传值,在注册通知的时候无需值,因此此处可填nil 
     * 
     */  
    [[NSNotificationCenter defaultCenter] addObserver:self  
                                             selector:@selector(respondsToNotification:)  
                                                 name:@"notification"  
                                               object:nil];  
}  

#pragma mark - responds notification  

// 处理通知,在此处获取从发送通知的控制器传过来的值  
- (void)respondsToNotification:(NSNotification *)info {  

}  

steps 2:发送通知:在DetailViewController.m文件处理返回按钮方法中,发送通知,传值到主界面,发送通知时的标识必须与注册通知时的标识一致。

- (void)respondsToButton:(UIButton *)sender {  

    // 发送通知:通知标识必须与注册通知时的标识一致  
    // 方法1:如果只传一个值,可调用此方法  
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notification"  
                                                        object:@"admin"];  

    // 方法2:如果传多个值,可将值以键值对(key-value)的形式存入字典传到需要的控制器  
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notification"  
                                                        object:nil  
                                                      userInfo:@{@"userName" : @"admin"}];  
}  

steps 3:处理通知:在HomeViewController.m文件处理通知方法中,获取值。

#pragma mark - responds notification  

// 处理通知,在此处获取从发送通知的控制器传过来的值  
- (void)respondsToNotification:(NSNotification *)info {  

    // 获取用户信息字典  
    NSDictionary *dict = info.userInfo;  
    // 获取用户名  
    NSString *userName = [dict objectForKey:@"userName"];  
    // 打印用户名  
    NSLog(@"userName is ‘%@’.", userName); // 输出"userName is ‘admin’."  

}  

steps 4:移除通知:通知在界面被释放的时候一定记得移除,否则可能会导致程序的奔溃。移除通知在注册通知控制器中的[dealloc]方法中实现。

 - (void)dealloc  
{  
    // 移除通知  
    [[NSNotificationCenter defaultCenter] removeObserver:self];  
}  

  • 注意

通知传值的使用会贯穿如下4个步骤:注册通知 -> 发送通知 -> 处理通知 -> 移除通知

通知必须先注册再使用,通知必须在不需要的时候调用remove方法移除。

协议传值

协议传值又称代理传值,可直接将需要传递的值从委托方传送至代理人,协议传值可用于从下一个视图控制器传值到上一个视图控制器(详情页传值到主页)

现假定主页是详情页的代理。

  • 传值步骤:

steps 1:在DetailViewController.h文件中声明协议,并且设置代理属性。

#import <UIKit/UIKit.h>  

@protocol myDelegate <NSObject>  

- (void)getUserName:(NSString *)userName; /**< 协议传值 */  

@end  

@interface DetailViewController : UIViewController  

@property (nonatomic, assign)id <myDelegate> delegate; /**< 声明代理人 */  

@end  

steps 2:在DetailViewController.m文件处理返回按钮方法中调用协议方法传值。

- (void)respondsToButton:(UIButton *)sender {  

    // 让代理人调用协议方法,并且传值。  
    [self.delegate getUserName:@"admin"];  

}  

steps 3:在HomeViewController.m文件处理界面跳转按钮方法中初始化详情视图控制器,设置详情视图控制器协议代理为self(主页),并且遵守协议。

- (void)respondsToButton:(UIButton *)sender {  

    // 初始化详情视图控制器  
    DetailViewController *detailVc = [[DetailViewController alloc] init];  

    // 设置代理,并且遵守<myDelegate>  
    detailVc.delegate = self;  

    // 模态切换(界面跳转)  
    [self presentViewController:detailVc animated:YES completion:nil];  
}  

steps 4:在HomeViewController.m中实现协议方法,获取值。

#pragma mark - <myDelegate>  
// 实现协议方法,获取值  
- (void)getUserName:(NSString *)userName {  

    // 获取打印userName的值  
    NSLog(@"userName is ‘%@’.", userName); // 输出"userName is ‘admin’."  
}  

单例传值

单例贯穿整个应用程序声明周期,利用单例传值适用于任何控制器,使用前提是在获取值的时候必须保证单例属性有值,否则获取值为nil。

此处模拟从主页视图控制器传值到详情视图控制器。

  • 传值步骤:

steps 1:创建单例,继承于NSObject,任意命名,必须符合规范。此处创建单例类名为Singleton。

steps 2:在Singleton.h中声明传值属性,并且声明单例类便利构造器。

@interface Singleton : NSObject  

@property (nonatomic, strong) NSString *userName; /**< 单例属性 */  

+ (instancetype)defaultSingleton; /**< 单例便利构造器 */  

@end  

steps 3:在Singleton.m文件中实现遍历构造器方法。

#import "Singleton.h"  

static Singleton *singleton = nil;  

@implementation Singleton  

+ (instancetype)defaultSingleton {  

    // GCD创建单例,效率更高,性能更好,消耗更低。  
    static dispatch_once_t onceToken;  
    dispatch_once(&onceToken, ^{  
        singleton = [[Singleton alloc] init];  
    });  
    return singleton;  
}  
@end  

steps 4:在HomeViewController.m文件中获取单例实例,并且赋值单例属性。

// 单例属性赋值  
- (void)assignmentedSingletonValue {  

    // 获取单例实例,首先需导入Singleton.h  
    Singleton *singleton = [Singleton defaultSingleton];  

    // 单例属性赋值  
    singleton.userName = @"admin";  
}  

steps 5:在DetailViewController.m文件中获取单例属性。

// 获取单例属性  
- (void)getSingletonValue {  

    // 获取单例实例,首先需导入Singleton.h  
    Singleton *singleton = [Singleton defaultSingleton];  

    // 获取单例属性值  
    NSString *userName = singleton.userName;  

    // 获取打印userName的值  
    NSLog(@"userName is ‘%@’.", userName); // 输出"userName is ‘admin’."  

}  

NSUserDefaults传值

NSUserDefaults系统单例传值和自定义单例传值基本一致,首先需保证NSUserDefaults对应key中有值。

此处模拟主页视图控制器传值到详情视图控制器。

  • 传值步骤:

steps 1:在HomeViewController.m中获取NSUserDefaults实例,并且存值。

- (void)saveValueInUserDefaults {  

    // 获取NSUserDefaults实例  
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  

    // 存值  
    [defaults setObject:@"admin" forKey:@"userName"];  

    // 同步数据  
    [defaults synchronize];  
}

steps 2:在DetailViewController.m中获取值

- (void)getValueInUserDefaults {  

    // 获取NSUserDefaults实例  
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  

    // 根据key获取值  
    NSString *userName = [defaults objectForKey:@"userName"];  

    // 获取打印userName的值  
    NSLog(@"userName is ‘%@’.", userName); // 输出"userName is ‘admin’."  

}

Block块传值

block在传值中主要用于回调。

现模拟从详情视图控制器传值到主页视图控制器。

  • DetailViewController.h文件
#import <UIKit/UIKit.h>  

// steps 1 声明block类型  

typedef void(^CallBack)(NSString *context);  

@interface DetailViewController : UIViewController  

// steps 2 声明block属性  

@property (nonatomic, copy) CallBack callBack;  

// steps 3 声明block传值方法  
 - (void)respondsButtonWithCallBack:(CallBack)callBack;  


@end

  • DetailViewController.m文件
// steps 4 赋值属性block  
 - (void)respondsButtonWithCallBack:(CallBack)callBack {  
    self.callBack = callBack;  
}  

// 处理按钮点击  
 - (void)respondsToButtonClick:(UIButton *)sender {  
    // steps 5 传值  
    if (self.callBack) {  

        self.callBack(_textField.text);  

        [self dismissViewControllerAnimated:YES completion:nil];  
    }  
}

  • ViewController.m文件
 - (void)respondsToButtonClick:(UIButton *)sender {  
    DetailViewController *detailVc = [[DetailViewController alloc] init];  

    // steps 6 调用block,取值  
    [detailVc respondsButtonWithCallBack:^(NSString *context) {  
        NSLog(@"get block value is '%@'.", context);  
    }];  
}

  • 总结

为block取别名,并且在参数列表中将需要传递的参数写成形参

设置block属性(注意使用copy)

设置一个方法持有当前block

在合适的地方进行调用类似于代理

在创建该对象的地方进行block方面的调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值