UI界面?zhèn)髦?/h2>

傳值需求

  • 將用戶信息 userInfo 作為傳值對(duì)象進(jìn)行傳遞。

場(chǎng)景一 主頁傳值到詳情頁

  • 現(xiàn)在模擬傳遞用戶名:userName。
屬性傳值
  1. 屬性傳值一般用于從主頁傳值到詳情頁。
  2. 傳值步驟:
steps 1:在DetailViewController.h文件中將需要獲取的值聲明成屬性。
#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController

@property (nonatomic, strong)NSString *userInfo; /**< 用戶信息 */

@end

steps 2:在HomeViewController.m文件中導(dǎo)入頭文件“DetailViewController.h”,然后在界面跳轉(zhuǎn)邏輯處理方法中初始化DetailViewController,并通過點(diǎn)語法給屬性u(píng)serInfo賦需要傳遞的值。
- (void)respondsToButton:(UIButton *)sender {

    // 初始化詳情視圖控制器n
    DetailViewController *detailVc = [[DetailViewController alloc] init];

    // 屬性傳值:賦值
    NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
    detailVc.userInfo = userInfo;

    // 模態(tài)切換(界面跳轉(zhuǎn))
    [self presentViewController:detailVc animated:YES completion:nil];

}

steps 3:在DetailViewController.m文件viewDidLoad方法中獲取userName的值,此時(shí)獲取到的值就是從主頁傳過來的值。
- (void)viewDidLoad {
    [super viewDidLoad];

    NSLog(@"%@", userInfo);
}
init傳值
  1. init方法傳值與屬性傳值類似,一般用于從主頁傳值到詳情頁。
steps 1:在DetailViewController.h文件中聲明init方法。
- (instancetype)initWithUserInfo:(NSDictionary *)userInfo; /**< init傳值方法聲明 */
steps 2:在HomeViewController.m文件中導(dǎo)入頭文件“DetailViewController.h”,然后在界面跳轉(zhuǎn)邏輯處理方法中通過initWithUserInfo:方法初始化DetailViewController并賦值。
- (void)respondsToButton:(UIButton *)sender {

    NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};

    // 初始化詳情視圖控制器
    DetailViewController *detailVc = [[DetailViewController alloc] initWithUserInfo:userInfo];

    // 模態(tài)切換(界面跳轉(zhuǎn))
    [self presentViewController:detailVc animated:YES completion:nil];

}
steps 3:在DetailViewController.m文件中重寫init方法,即實(shí)現(xiàn)initWithUserInfo:方法,在這個(gè)方法中獲取userName的值,此時(shí)獲取到的值就是從主頁傳過來的值。
- (instancetype)initWithUserInfo:(NSDictionary *)userInfo {
    if (self = [super init]) {
        NSLog(@"%@", userInfo);
    }
    return self;
}

場(chǎng)景二 詳情頁傳值到主頁

Block塊傳值
  • block在傳值中主要用于回調(diào),現(xiàn)模擬從詳情視圖控制器傳值到主頁視圖控制器。
steps 1:在 DetailViewController.h文件中聲明block類型、屬性以及block回調(diào)方法。
#import <UIKit/UIKit.h>

// 1 聲明block類型

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

@interface DetailViewController : UIViewController

// 2 聲明block屬性

@property (nonatomic, copy) CallBackBlock callBackBlock;

/ 3 聲明block傳值方法
- (void)getsUserInfoWithBlocks:(CallBackBlock)callBackBlock;


@end
steps 2:在 DetailViewController.m文件中,實(shí)現(xiàn)如下操作:
// 4 賦值屬性block
- (void)getsUserInfoWithBlocks:(CallBackBlock)callBackBlock {
    self.callBackBlock = callBackBlock;
}

// 處理按鈕點(diǎn)擊
- (void)respondsToButtonClick:(UIButton *)sender {
    // 5 傳值
    if (self.callBack) {

        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
        self.callBackBlock(userInfo);

        [self dismissViewControllerAnimated:YES completion:nil];
    }
}
steps 3:在 ViewController.m文件實(shí)現(xiàn)如下操作:
- (void)respondsToButtonClick:(UIButton *)sender {
    DetailViewController *detailVc = [[DetailViewController alloc] init];

    // 6 調(diào)用block,取值
    [detailVc getsUserInfoWithBlocks:^(NSDictionary *userInfo) {
    NSLog(@"%@", userInfo);
}];

    // 模態(tài)切換(界面跳轉(zhuǎn))
    [self presentViewController:detailVc animated:YES completion:nil];
}
  • Tips:
    1、為block取別名,可在參數(shù)列表中將需要傳遞的參數(shù)寫成形參;
    2、設(shè)置block屬性注意使用copy關(guān)鍵字;
    3、設(shè)置一個(gè)方法持有當(dāng)前block;
    4、在合適的地方進(jìn)行調(diào)用類似于代理;
    5、在創(chuàng)建該對(duì)象的地方進(jìn)行block方面的調(diào)用;
協(xié)議傳值
  1. 協(xié)議傳值又稱代理傳值,可直接將需要傳遞的值從委托方傳送至代理人,協(xié)議傳值可用于從下一個(gè)視圖控制器傳值到上一個(gè)視圖控制器(詳情頁傳值到主頁),現(xiàn)假定主頁是詳情頁的代理。
  • 傳值步驟
steps 1:在DetailViewController.h文件中聲明協(xié)議,并且設(shè)置代理屬性。
#import <UIKit/UIKit.h>


// @class 意在告訴編譯器,“DetailViewController”為一個(gè)類。

@class DetailViewController;

// @protocol 聲明協(xié)議
// 協(xié)議命名規(guī)范:類名 + delegate

@protocol DetailViewControllerDelegate <NSObject>

// @optional:聲明可選協(xié)議方法
// 協(xié)議方法的聲明模仿蘋果官方聲明方式,將類實(shí)例以及傳遞信息一并暴露在參數(shù)中

@optional

- (void)detailViewController:(DetailViewController *)detailViewController goBackWithUserInfo:(NSDictionary *)userInfo;

@end

@interface DetailViewController : UIViewController

// 聲明代理屬性,注意關(guān)鍵字使用 weak || assign,可避免保留環(huán)
@property (nonatomic, weak) id <DetailViewControllerDelegate> delegate;
@end
steps 2:在DetailViewController.m文件處理返回按鈕方法中調(diào)用協(xié)議方法傳值。
- (void)respondsToButton:(UIButton *)sender {

    // 首先判斷代理人是否存在并且是否遵守協(xié)議并且實(shí)現(xiàn)了協(xié)議方法

    if (_delegate && [_delegate respondsToSelector:@selector(detailViewController:goBackWithUserInfo:)]) {

        // 如果滿足判斷條件,則讓代理執(zhí)行協(xié)議方法,此處讓代理人執(zhí)行協(xié)議方法,在代理人那個(gè)控制器中的協(xié)議方法會(huì)被執(zhí)行;

        // 通常經(jīng)協(xié)議傳值在此處調(diào)用方法時(shí),直接給參數(shù)賦值即可,在代理人控制器實(shí)現(xiàn)的協(xié)議方法中,可直接獲取此處設(shè)置的值;

        NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};

        [_delegate detailViewController:self goBackWithUserInfo:userInfo];

    }
}
steps 3:在HomeViewController.m文件處理界面跳轉(zhuǎn)按鈕方法中初始化詳情視圖控制器,設(shè)置詳情視圖控制器協(xié)議代理為self(主頁),并且遵守<DetailViewControllerDelegate>協(xié)議。
- (void)respondsToButton:(UIButton *)sender {
    // 初始化詳情視圖控制器
    DetailViewController *detailVc = [[DetailViewController alloc] init];

    // 設(shè)置代理,并且遵守<DetailViewControllerDelegate>
    detailVc.delegate = self;

    // 模態(tài)切換(界面跳轉(zhuǎn))
    [self presentViewController:detailVc animated:YES completion:nil];
}
steps 4:在HomeViewController.m中實(shí)現(xiàn)<DetailViewControllerDelegate>協(xié)議方法,獲取值。
#pragma mark *** DetailViewControllerDelegate ***
// 實(shí)現(xiàn)協(xié)議方法,獲取值
- (void)detailViewController:(DetailViewController *)detailViewController goBackWithUserInfo:(NSDictionary *)userInfo {
    NSLog(@"%@", userInfo);
}

場(chǎng)景三 多界面?zhèn)髦?/h3>

通知傳值
  1. 通知傳值適用于任意控制器(界面),不管兩個(gè)控制器之間是否有關(guān)聯(lián),只需滿足一個(gè)條件,在傳值的時(shí)候必須保證通知已經(jīng)被設(shè)定,即已添加通知(觀察者observer)?,F(xiàn)假設(shè)從詳情界面?zhèn)髦档街鹘缑妫磸南乱粋€(gè)界面?zhèn)髦档缴弦粋€(gè)界面,具體實(shí)現(xiàn)方式如下。
  • 傳值步驟
steps 1:注冊(cè)通知:為保證在傳值時(shí)通知已經(jīng)被設(shè)定,因此需要在HomeViewController.m文件中注冊(cè)通知。
#import "HomeViewController.h"
#import "DetailViewController.h"

@interface HomeViewController ()

@end

@implementation HomeViewController

- (instancetype)init {
    self = [super init];
    if (self) {

    /**
     *  注冊(cè)通知
     *
     *  @param observer 觀察者對(duì)象
     *  @param selector 觸發(fā)方法,即當(dāng)收到通知之后執(zhí)行的方法
     *  @param name     通知代號(hào),即通知標(biāo)識(shí),發(fā)送通知時(shí)的標(biāo)識(shí)必須和注冊(cè)通知時(shí)的標(biāo)識(shí)一致
     *  @param object   是否傳值,在注冊(cè)通知的時(shí)候無需值,因此此處可填nil
     *
     */

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondsToNotification:) name:@"notification_name" object:nil];
    }
    return self;
}

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

#pragma mark *** responds notification ***

// 處理通知,當(dāng)接收到通知的時(shí)候該方法會(huì)自動(dòng)調(diào)用
// 在此處獲取從發(fā)送通知的控制器傳過來的值
- (void)respondsToNotification:(NSNotification *)info {

}
steps 2:發(fā)送通知:在DetailViewController.m文件處理返回按鈕方法中,發(fā)送通知,傳值到主界面,發(fā)送通知時(shí)的標(biāo)識(shí)必須與注冊(cè)通知時(shí)的標(biāo)識(shí)一致。
- (void)respondsToButton:(UIButton *)sender {

    // 發(fā)送通知:通知標(biāo)識(shí)必須與注冊(cè)通知時(shí)的標(biāo)識(shí)一致
    // 將需要傳遞的信息以字典形式賦給 userInfo 參數(shù)
    NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
    [[NSNotificationCenter defaultCenter] postNotificationName:@"notification_name" object:nil userInfo:userInfo];

}
steps 3:處理通知:在HomeViewController.m文件處理通知方法中,獲取值。
#pragma mark *** responds notification ***

// 處理通知,在此處獲取從發(fā)送通知的控制器傳過來的值
// 注意:info參數(shù)包含兩個(gè)屬性,可通過點(diǎn)語法訪問。
// 1、name:為對(duì)應(yīng)通知的標(biāo)識(shí)
// 2、userInfo:為傳遞的信息
- (void)respondsToNotification:(NSNotification *)info {
    NSLog(@"%@", info.userInfo); 
}
steps 4:移除通知:通知在界面被釋放的時(shí)候一定記得移除,否則可能會(huì)導(dǎo)致程序的奔潰。移除通知在注冊(cè)通知控制器中的[dealloc]方法中實(shí)現(xiàn)。
- (void)dealloc
{
    // 移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
  • 注意
    1、通知傳值的使用會(huì)貫穿如下4個(gè)步驟:注冊(cè)通知 -> 發(fā)送通知 -> 處理通知 -> 移除通知
    2、通知必須先注冊(cè)再使用,通知必須在不需要的時(shí)候調(diào)用remove方法移除。
單例傳值
  1. 單例貫穿整個(gè)應(yīng)用程序聲明周期,利用單例傳值適用于任何控制器,使用前提是在獲取值的時(shí)候必須保證單例屬性有值,否則獲取值為nil,此處模擬從主頁視圖控制器傳值到詳情視圖控制器。
  • 傳值步驟
steps 1:創(chuàng)建單例,繼承于NSObject,任意命名,必須符合規(guī)范。此處創(chuàng)建單例類名為Singleton。
steps 2:在Singleton.h中聲明傳值屬性,并且聲明單例類便利構(gòu)造器。
@interface Singleton : NSObject

@property (nonatomic, strong) NSDictionary *userInfo; /**< 單例屬性 */

+ (instancetype)defaultSingleton; /**< 單例便利構(gòu)造器 */

@end
steps 3:在Singleton.m文件中實(shí)現(xiàn)遍歷構(gòu)造器方法。
#import "Singleton.h"

static Singleton *singleton = nil;

@implementation Singleton

+ (instancetype)defaultSingleton {

    // GCD創(chuàng)建單例,效率更高,性能更好,消耗更低。
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[Singleton alloc] init];
    });
    return singleton;
}
@end
steps 4:在HomeViewController.m文件中獲取單例實(shí)例,并且賦值單例屬性,賦值位置可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
// 單例屬性賦值
- (void)viewDidLoad {
    [super viewDidLoad];

    // 獲取單例實(shí)例,首先需導(dǎo)入Singleton.h
    Singleton *singleton = [Singleton defaultSingleton];

    // 單例屬性賦值
    NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
    singleton.userInfo = userInfo;
}
steps 5:在DetailViewController.m文件中獲取單例屬性,取值位置可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
// 獲取單例屬性
- (void)viewDidLoad {
    [super viewDidLoad];

    // 獲取單例實(shí)例,首先需導(dǎo)入Singleton.h
    Singleton *singleton = [Singleton defaultSingleton];

    // 獲取單例屬性值
    NSLog(@"%@", singleton.userInfo);
}
NSUserDefaults傳值
  1. NSUserDefaults系統(tǒng)單例傳值和自定義單例傳值基本一致,首先需保證NSUserDefaults對(duì)應(yīng)key中有值,此處模擬主頁視圖控制器傳值到詳情視圖控制器
  • 傳值步驟
steps 1:在HomeViewController.m中獲取NSUserDefaults實(shí)例,并且存值。
- (void)saveValueInUserDefaults {

    // 獲取NSUserDefaults實(shí)例
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    // 存值
    NSDictionary *userInfo = @{@"name":@"Charles", @"age":@(22)};
    [defaults setObject:userInfo forKey:@"userInfo"];

    // 同步數(shù)據(jù)
    [defaults synchronize];
}
steps 2:在DetailViewController.m中獲取值
- (void)getValueInUserDefaults {

    // 獲取NSUserDefaults實(shí)例
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    // 根據(jù)key獲取值
    NSDictionary *userInfo = [defaults objectForKey:@"userInfo"];

    NSLog(@"%@", userInfo);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,070評(píng)論 25 709
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 47,163評(píng)論 22 665
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,394評(píng)論 4 61
  • 會(huì)不會(huì) 有一天 憂郁成疾 死在一場(chǎng)深沉的痛楚里 無休無止 蔓延于血液 縱影子瘦落成鬼 游蕩飄獨(dú)的北寒中 糾纏著 滄...
    樊小四閱讀 179評(píng)論 3 8
  • 閱讀小黃書《善解童貞》第二天“戀父戀母” 《親密關(guān)系》中有一節(jié)是關(guān)于性的罪惡感的。講的是兩性之間并不能真正享受性,...
    竹筠益閱讀 1,188評(píng)論 0 2

友情鏈接更多精彩內(nèi)容