1. 程式人生 > >iOS詳細解析檢視控制器的正向和逆向傳值

iOS詳細解析檢視控制器的正向和逆向傳值

本文主要介紹在不同的檢視控制器之間進行傳值,分為兩種傳值方式,正向傳值比較容易,逆向傳值相對於正向來說麻煩一點,需要使用代理或者是block

一、正向傳值 正向傳值只需要在第一個檢視控制器中“拿到”第二個檢視控制器,然後在跳轉之前將第一個檢視控制器的值賦值給第二個檢視控制器所需要獲得這個值的屬性。跳轉的方式有很多種,如果需要可以看另外一篇文章,這裡就直接用 presentViewController 來示範: 說明:下面的程式碼是關聯著storyboard 在ViewController.m檔案中
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textField1;
@property (weak, nonatomic) IBOutlet UITextField *textField2;
@end

這是跳轉button的事件方法
- (IBAction)presentViewController:(id)sender
{
    // 在storyboard中設定secondViewController的identifier為123
    SecondViewController *secondVc = [self.storyboard instantiateViewControllerWithIdentifier:@"123"];
    // 關於傳值的程式碼
    secondVc.data1 = self.textField1.text;
    secondVc.data2 = self.textField2.text;
    // 注意在這裡不能夠直接給第二個檢視控制器的lable賦值,例如下面的程式碼就是不正確的
#if 0
    secondVc.lable1.text = self.textField1.text;
    secondVc.lable2.text = self.textField2.text;
#endif
    // 進行跳轉
    [self presentViewController:secondVc animated:YES completion:nil];
}
在SecondViewController.h檔案中
@property (nonatomic, strong) NSString *data1;
@property (nonatomic, strong) NSString *data2;
@property (weak, nonatomic) IBOutlet UILabel *lable1;
@property (weak, nonatomic) IBOutlet UILabel *lable2;

這是跳轉的button的事件方法
- (IBAction)presentToSecondVIewController:(id)sender
{
    SecondViewController *secondVc = [self.storyboard instantiateViewControllerWithIdentifier:@"123"];
    // 將自己設定為第二個檢視控制器的代理物件
    secondVc.delegate = self;
    [self presentViewController:secondVc animated:YES completion:nil];
}

在SecondViewController.m檔案中
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];
    self.lable1.text = self.data1;
    self.lable2.text = self.data2;
}

二、逆向傳值 關於逆向傳值,介紹兩種最常見的方法,一種是代理/協議,一種是block,對於這兩種方法的介紹利用實際的程式碼進行詳細說明 1、代理/協議 說明:下面程式碼也是依賴於storyboard的 在ViewController.m檔案中(需要去宣告代理)
@property (weak, nonatomic) IBOutlet UILabel *lable;

這是跳轉button的事件方法
- (IBAction)presentToSecondVIewController:(id)sender
{
    // 在storyboard中將第二個檢視控制器的identifier設定為了123
    SecondViewController *secondVc = [self.storyboard instantiateViewControllerWithIdentifier:@"123"];
    // 將自己設定為第二個檢視控制器的代理物件
    secondVc.delegate = self;
    [self presentViewController:secondVc animated:YES completion:nil];
}
#pragma mark - 第二個檢視控制器的代理方法
- (void)passValue:(NSString *)lableText
{
    self.lable.text = lableText;
}
在SecondViewController.h中
// 1、宣告協議
@protocol SecondViewControllerDelegate <NSObject>
@optional
// 2、協議的方法
- (void)passValue :(NSString *)lableText;
@end

@interface SecondViewController : ViewController
// 3、定義協議屬性
@property (nonatomic,weak)id<SecondViewControllerDelegate> delegate;

在SecondViewController.m中

- (IBAction)dissmissBackToVIewController:(id)sender
{
    // 判斷這個協議方法是否被實現
    if ([self.delegate respondsToSelector:@selector(passValue:)]) {
        // 如果實現了就將第二個檢視控制器中lable的值給傳到代理方法中,使得第一個類在實現代理方法的時候可以能夠或者這個值(這個值在實現代理方法的時候就是方法的引數lableText)
        [self.delegate passValue:self.lable.text];
    }
    // 跳轉會第一個檢視控制器
    [self dismissViewControllerAnimated:YES completion:nil];
}

2、block
說明:下面的程式碼是依賴於storyboard的 在ViewController.m中
這是跳轉button的事件方法
@property (weak, nonatomic) IBOutlet UILabel *lable;

- (IBAction)tureToSecondVc:(id)sender
{
    // 在storyboard裡面設定第二個檢視控制器的identifier為123
    SecondViewController *secondVc = [self.storyboard instantiateViewControllerWithIdentifier:@"123"];
    // 實現block
    secondVc.backValue = ^(NSString *tel)
    {
        self.lable.text = tel;
    };
    [self presentViewController:secondVc animated:YES completion:nil];
}

在SecondViewController.h中
@property (weak, nonatomic) IBOutlet UILabel *lable;

// 宣告一個block(block的定義使用copy)
@property (copy , nonatomic) void(^backValue)(NSString *lableText);

在SecondViewController.m中 這是返回button的事件方法
- (IBAction)dissmissBackToViewController:(id)sender
{
    // 當返回的時候,在block中傳值
    self.backValue(self.lable.text);
    [self dismissViewControllerAnimated:YES completion:nil];
}