编辑
使用代码块向后传值
本文访问次数:0
  1. 1. 问题
  2. 2. 办法
    1. 2.1. 向前传值
    2. 2.2. 向后传值
      1. 2.2.1. 代码块
      2. 2.2.2. 代理模式

问题

在ViewController之前传值分为两种情况:

  1. 向前传值。
  2. 向后传值。
    例如我们的项目中有两个ViewController,分别为ViewControllerA(以下简称A)和ViewControllerB(以下简称B),A打开了B,B需要一个参数用来初始化,那么A就要提供这个参数,这种情况就是向前传值,代码如下:
    //this happens in ViewControllerA
    ViewControllerB*viewControllerB = [[ViewControllerB alloc]init];
    viewControllerB.initValue = @"initValue";
    [self.navigationController pushViewController:viewControllerB animated:YES];
    
    A打开B是有自己的目的的,他需要B根绝相关参数或者服务器端的返回值提供一个结果,然后使用这个结果做一些事情,这种情况就是向后传值。

办法

向前传值

处理向前传值有两种情况,第一种,使用代码打开的方式,这种情况下只需将需要初始化的值声明在B的头文件中,然后在A中对其进行赋值即可(即以上代码)。第二种,使用StoryBoard打开,这种情况需要采用以下代码赋值,不过仍然在B的头文件中声明

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"showDetailSegue"]){
        ViewControllerB *viewControllerB = (ViewControllerB *)segue.destinationViewController;
        controller.initValue = @“hi”;
    }

}
//如果ViewControllerB是包裹在NavigationController中的,需要稍微改下代码
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"showDetailSegue"]){
        UINavigationController *navigationController = (UINavigationController *)segue.destinationViewController;
        ViewControllerB *viewControllerB = (ViewControllerB *)navController.topViewController;
        controller.initValue = @“hello”;
    }
}

向后传值

代码块

向后传值可以采用两种方式,代码块和代理模式。以下代码为使用代码块的方式:
首先在ViewControllerB的头文件(.h)中声明代码块

//ViewControllerB.h
@interface ViewControllerB : UIViewController
@property (nonatomic, copy) void (^completion) (NSInteger, id);
...
@end

然后在ViewControllerA中给代码块赋值

//ViewControllerA.m
ViewControllerB*viewControllerB = [[ViewControllerB alloc]init];
viewControllerB.initValue = @"initValue";
viewControllerB.completion = ^(NSInteger resultCode, id data) {
    if (resultCode == 0) {
        //Maybe you should check if data is kind of dictionary
        NSDictionary*dictionary = data;
        //do the work
        ...
    }
};
[self.navigationController pushViewController:viewControllerB animated:YES];

最后在关闭ViewControllerB之前提供结果即可

//ViewControllerB.m
self.completion (0, @{@"key":@"value"});
[self.navigationController popViewControllerAnimated:YES];

代理模式

以下代码为使用代理模式的方式

首先在ViewControllerB的头文件(.h)中声明协议和代理属性

//ViewControllerB.h
@protocol ViewControllerCompleteDelegate <NSObject>
@required
- (void)complete:(NSInteger)requestCode result:(NSInteger)resultCode data:(id)data;
@end

@interface GenderViewController : UIViewController
@property (nonatomic, strong) id<ViewControllerCompleteDelegate> completeDelegate;
...
@end

然后在ViewControllerA中实现协议并给代理属性赋值

//ViewControllerA.m
@interface ViewControllerA ()<ViewControllerCompleteDelegate>
...
@end
//实现协议
- (void)complete:(NSInteger)requestCode result:(NSInteger)resultCode data:(id)data {
    NSLog (@"the result is %@", data);
}

ViewControllerB*viewControllerB = [[ViewControllerB alloc]init];
viewControllerB.initValue = @"initValue";
genderVC.completeDelegate = self;
[self.navigationController pushViewController:viewControllerB animated:YES];

最后在关闭ViewControllerB之前提供结果即可

//ViewControllerB.m
[self.completeDelegate complete:0
                             result:0
                               data:@{@"key":@"value"}];
[self.navigationController popViewControllerAnimated:YES];
没有任何评论