iOS筆記-控制器傳值總結(jié)(OC)

Coder_CYX

導(dǎo)讀:

iOS開(kāi)發(fā)中,你肯定遇到過(guò)控制器之間的值或模型的傳遞,本文將從兩種創(chuàng)建控制器的方式&兩種值傳遞的方向,分別介紹了如何進(jìn)行控制器之間值傳遞的方法及步驟。因?yàn)椴┲髦R(shí)水平有限,這只是實(shí)現(xiàn)值傳遞的其中幾種方式,如果您有更好的建議,歡迎提出,大家一起討論,共同進(jìn)步。

純代碼方式


控制器之間傳值

  • 兩個(gè)要點(diǎn):
    • 1.接收方一定要有屬性去接收
    • 2.傳遞方需要拿到接收方,進(jìn)行直接賦值

順傳

  • 上一級(jí)控制器傳遞給下一級(jí)控制器。
  • 實(shí)現(xiàn)策略:直接拿到下一級(jí)控制器,拿到以后,做什么事情都行(對(duì)其屬性賦值)
  • 實(shí)現(xiàn)代碼:

上一級(jí)控制器(傳遞方):

#import "CYXContactViewController.h"
#import "CYXContact.h"
#import "CYXEditViewController.h"
@implementation CYXContactViewController
// 準(zhǔn)備好segue線之后,跳轉(zhuǎn)之前會(huì)調(diào)用
// 做一些數(shù)據(jù)之間的傳值
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    //獲取目標(biāo)控制器
    CYXEditViewController *editVc = segue.destinationViewController;
    // 獲取當(dāng)前選中的角標(biāo)
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    // 獲取選中的cell對(duì)應(yīng)的模型
    CYXContact *cont = self.contactArr[indexPath.row];
    // 傳遞選中的cell對(duì)應(yīng)的模型
    editVc.contact = cont;
}

@end

下一級(jí)控制器(接收方):

#import <UIKit/UIKit.h>
@class CYXContact;
@interface CYXEditViewController : UIViewController
/** 用于存儲(chǔ)聯(lián)系人頁(yè)傳來(lái)的模型 */
@property (strong, nonatomic) CYXContact * contact;
@end

逆?zhèn)?/h4>
  • 下一級(jí)控制器傳遞給上一級(jí)控制器。
  • 實(shí)現(xiàn)策略:使用代理。上一級(jí)控制器作為下一級(jí)控制器的代理,監(jiān)聽(tīng)下一級(jí)控制器的事情。
  • 實(shí)現(xiàn)代碼:

上一級(jí)控制器(接收方)

**//1.遵守協(xié)議**
@interface CYXContactViewController ()<CYXAddViewControllerDelegate>

**//2.設(shè)置代理為self控制器**
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    CYXAddViewController *addVc = segue.destinationViewController;
    addVc.delegate = self;
}

**//3.實(shí)現(xiàn)代理方法**
- (void)addViewController:(CYXAddViewController *)addVc didAddContact:(CYXContact *)contact{
    [self.contactArr addObject:contact];
    [self.tableView reloadData];
}

下一級(jí)控制器(傳遞方)

.h 文件:
#import <UIKit/UIKit.h>
@class CYXContact,CYXAddViewController;

@protocol  CYXAddViewControllerDelegate<NSObject>
@optional

**//1.定義代理方法**#
- (void)addViewController:(CYXAddViewController *)addVc didAddContact:(CYXContact *)contact;
@end

@interface CYXAddViewController : UIViewController

**//2.聲明代理屬性**
@property (nonatomic,weak) id<CYXAddViewControllerDelegate>  delegate;
@end

.m 文件:
@implementation CYXAddViewController

// 逆?zhèn)?// (1)在跳轉(zhuǎn)之前,在傳遞方把接收方先保存起來(lái)
// (2)等需要真的給接收方傳值的時(shí)候,直接拿到它傳值
// 點(diǎn)擊添加按鈕的時(shí)候調(diào)用
- (IBAction)addContact:(id)sender {
    // 把姓名和電話文本框的內(nèi)容包裝成模型
    CYXContact *contact = [CYXContact contactWithName:_nameField.text phone:_phoneField.text];

**// 3.調(diào)用代理方法,通知代理接收聯(lián)系人模型**
    if ([_delegate respondsToSelector:@selector(addViewController:didAddContact:)]) {
        [_delegate addViewController:self didAddContact:contact];
    }
    // 回到上一個(gè)控制器
    [self.navigationController popViewControllerAnimated:YES];


}

Storyboard方式


認(rèn)識(shí)Segue

  • 什么是Segue

    • Storyboard上每一根用來(lái)界面跳轉(zhuǎn)的線,都是一個(gè)UIStoryboardSegue對(duì)象(簡(jiǎn)稱Segue)
  • Segue的屬性

    • 唯一標(biāo)識(shí):@property (nonatomic, readonly) NSString *identifier;
    • 來(lái)源控制器:@property (nonatomic, readonly) id sourceViewController;
    • 目標(biāo)控制器:@property (nonatomic, readonly) id destinationViewController;
  • Segue的類型(可分為兩大類)

    • 自動(dòng)型:點(diǎn)擊某個(gè)控件后(比如按鈕),自動(dòng)執(zhí)行Segue,自動(dòng)完成界面跳轉(zhuǎn)

      • 按住Control鍵,直接從控件拖線到目標(biāo)控制器
      • 如果點(diǎn)擊某個(gè)控件后,不需要做任何判斷,一定要跳轉(zhuǎn)到下一個(gè)界面,建議使用自動(dòng)Segue;
    • 手動(dòng)型:需要通過(guò)寫代碼手動(dòng)執(zhí)行Segue,才能完成界面跳轉(zhuǎn)

      • 按住Control鍵,從來(lái)源控制器拖線到目標(biāo)控制器
      • 手動(dòng)型的Segue需要設(shè)置一個(gè)標(biāo)識(shí)(Identifier)
      • 在恰當(dāng)?shù)臅r(shí)刻,使用perform方法執(zhí)行對(duì)應(yīng)的Segue,完成界面跳轉(zhuǎn)
      [self performSegueWithIdentifier:@"login2contacts" sender:nil];
      // Segue必須由來(lái)源控制器來(lái)執(zhí)行,也就是說(shuō),這個(gè)perform方法必須由來(lái)源控制器來(lái)調(diào)用
      
      
      • 如果點(diǎn)擊某個(gè)控件后,需要做一些判斷,也就是說(shuō):滿足一定條件后才跳轉(zhuǎn)到下一個(gè)界面,建議使用“手動(dòng)型Segue”
  • performSegueWithIdentifier:sender:方法的完整執(zhí)行過(guò)程:

    • 1.根據(jù)identifier去storyboard中找到對(duì)應(yīng)的Segue線,新建UIStoryboardSegue對(duì)象 - 設(shè)置Segue對(duì)象的sourceViewController(來(lái)源控制器)
      • 新建并且設(shè)置Segue對(duì)象的destinationViewController(目標(biāo)控制器)
    • 2.調(diào)用sourceViewController(源控制器)的下面方法,做一些跳轉(zhuǎn)前的準(zhǔn)備工作并且傳入創(chuàng)建好的Segue對(duì)象
    // 準(zhǔn)備好segue線之后,跳轉(zhuǎn)之前會(huì)調(diào)用
    // 做一些數(shù)據(jù)之間的傳值
    -(void)prepareForSegue:(UIStoryboardSegue *)segue     sender:(id)sender
    {
    // 執(zhí)行跳轉(zhuǎn)
    CYXContactViewController *vc = segue.destinationViewController;
    // 傳值
    vc.accountStr = _accountField.text;
    

}

```
- 3.調(diào)用Segue對(duì)象的`- (void)perform;`方法開(kāi)始執(zhí)行界面跳轉(zhuǎn)操作
    - 如果segue的style是`push`
        - 取得`sourceViewController`所在的`UINavigationController`
        - 調(diào)用`UINavigationController`的`push`方法將`destinationViewController`壓入棧中,完成跳轉(zhuǎn)
    - 如果segue的style是`modal`
        - 調(diào)用`sourceViewController`的`presentViewController`方法將`destinationViewController`展示出來(lái)

模型的值發(fā)生改變時(shí)通知控制器(使用Notification通知)<跨控制器傳值也可采取這種方式>

  • 在上一個(gè)控制器修改了同一個(gè)模型數(shù)據(jù)
- (IBAction)saveBtnClick:(UIButton *)sender {
    //修改模型數(shù)據(jù)
    _contact.name = self.nameFiel.text;
    _contact.phonenum = self.phoneFiel.text;

    //發(fā)出通知
    [[NSNotificationCenter defaultCenter]postNotificationName:@"contactChange" object:nil];

    [self.navigationController popViewControllerAnimated:YES];
}

  • 在下一個(gè)展示模型數(shù)據(jù)的控制器接收通知,刷新視圖
- (void)viewDidLoad {
    [super viewDidLoad];
    //監(jiān)聽(tīng)模型更新通知
    [[NSNotificationCenter defaultCenter]addObserverForName:@"contactChange"
    object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        //此處處理監(jiān)聽(tīng)的事件
        //只要監(jiān)聽(tīng)到通知就會(huì)調(diào)用
        //這里是更新模型,刷新表格
        [self.tableView reloadData];
    }];

}

最后編輯于
?著作權(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)容

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