简体   繁体   中英

Passing data between ViewController and TabBar children

I am developing an application which has aa TableView. When I press any cell the app goes to the next ViewController. In this viewController I have created a TabBarController by code which has 3 children ViewControllers. So, I want to pass a variable from the TableView to the Children of the TabBar. I can pass the variable to the TabBar, I have watched it with the NSlog function. It is really weird for me that in the children ViewControllers I also have type a NSlog and the variable is null, but in the output I see first this.

2013-10-01 03:01:40.687 Prototype[38131:c07] proId (null) // This is the children log from vc2 ViewController  "YPProjectViewController"
2013-10-01 03:01:40.697 Prototype[38131:c07] projectID 433 // This is the TabBar LOG YPTabBarViewController 

Does somebody know why I can first the Children NSLog? Maybe there is the solution.

#import "YPTabBarViewController.h"
#import "YPProjectViewController.h"
#import "YPCommentsViewController.h"
#import "YPProposalsViewController.h"

@interface YPTabBarViewController ()
@property (nonatomic,strong)UITabBarController *tabBar;
@end

@implementation YPTabBarViewController
@synthesize tabBar;
@synthesize projectId = _projectId;

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setUpTabBar];

}

// Set up tabBar
-(void)setUpTabBar
{

        YPCommentsViewController *vc1 = [[YPCommentsViewController alloc] init];
        vc1.title = @"Comments";
        vc1.view.backgroundColor = [UIColor clearColor];
        UINavigationController *contentNavigationController = [[UINavigationController alloc] initWithRootViewController:vc1];

        YPProjectViewController *vc2 = [[YPProjectViewController alloc] init];
        vc2.title = @"Project";
        vc2.view.backgroundColor = [UIColor clearColor];

        vc2.proId = _projectId;
        NSLog(@"PROJECT ID %@", vc2.proId);
       // UINavigationController *contentNavigationController2 = [[UINavigationController alloc] initWithRootViewController:vc2];


        YPProposalsViewController *vc3 = [[YPProposalsViewController alloc] init];
        vc3.title = @"Proposal";
        vc3.view.backgroundColor = [UIColor clearColor];
        UINavigationController *contentNavigationController3 = [[UINavigationController alloc] initWithRootViewController:vc3];
        tabBar = [[UITabBarController alloc] init];
        tabBar.viewControllers = @[contentNavigationController,vc2,contentNavigationController3];
        tabBar.selectedIndex   = 1;

        [tabBar.view setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
        [tabBar willMoveToParentViewController:self];
        [self addChildViewController:tabBar];
        [tabBar didMoveToParentViewController:self];
        [self.view addSubview:tabBar.view];

}

In terms of understanding the problem, your NSLog statement in the "tab bar controller" is logging the value of vc2.proID immediately after setting it. But your NSLog output show us that that second tab's view controller is logging its results before that. That's why it's nil when the second tab's view controller's viewDidLoad logs it, because that log is happening before the tab bar controller had a chance to set the value and log it itself.

So, there are a couple of ways you could fix this:

  1. Right before your assignment of vc2.proId , you have an innocuous line of code that says:

     vc2.view.backgroundColor = [UIColor clearColor]; 

    That line of code triggers the second view controller's view to be loaded (and its viewDidLoad will be called). If you move the assignment of vc2.proId to before you start accessing any of vc2 's views, that will change the order that your NSLog statements appear (or, much better, move the setting of the background color into viewDidLoad of the child controllers).

  2. You could just create your own init method that accepts the project id as a parameter. That would also ensure that it's set before viewDidLoad . Thus, YPProjectViewController could have a method such as:

     - (id)initWithProjectId:(NSString *)projectId { self = [self init]; if (self) { _proId = projectId; } return self; } 

Two unrelated observations regarding the custom container calls:

  1. When you call addChildViewController , it calls willMoveToParentViewController for you. So you should remove the call to willMoveToParentViewController . See the documentation for that method .

  2. You might even want to retire these custom container calls altogether, and just make YPTabBarViewController a subclass of UITabBarController , itself, rather than UIViewController . That eliminates the need to custom container calls altogether. Clearly, if you have other needs for the custom container, then feel free, but it's redundant in this code sample.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM