在ViewController和TabBar子节点之间传递数据

时间:2013-10-01 01:10:52

标签: iphone ios objective-c uitableview uitabbarcontroller

我正在开发一个具有TableView的应用程序。当我按任何单元格时,应用程序将转到下一个ViewController。在这个viewController中,我通过代码创建了一个TabBarController,该代码有3个子ViewControllers。所以,我想将一个变量从TableView传递给TabBar的Children。我可以将变量传递给TabBar,我已经用NSlog函数看了它。我真的很奇怪,在子ViewControllers中我也输入了一个NSlog,变量为null,但在输出中我首先看到了这个。

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 

有人知道为什么我可以先成为儿童NSLog吗?也许有解决方案。

#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];

}

1 个答案:

答案 0 :(得分:2)

在理解问题方面,“标签栏控制器”中的NSLog语句在设置后立即记录vc2.proID的值。但是您的NSLog输出向我们显示第二个选项卡的视图控制器在之前记录其结果。这就是为什么当第二个选项卡的视图控制器的nil记录时它是viewDidLoad,因为在标签栏控制器有机会设置值并自行记录之前,该日志正在发生。

所以,有几种方法可以解决这个问题:

  1. 在您分配vc2.proId之前,您有一行无害的代码说:

    vc2.view.backgroundColor = [UIColor clearColor];
    

    该行代码触发第二个视图控制器的视图加载(并且将调用其viewDidLoad)。如果您在开始访问任何vc2.proId视图之前将vc2的分配移至,则会更改NSLog语句的显示顺序(或更好的是,移动设置背景颜色为子控制器的viewDidLoad

  2. 您可以创建自己的init方法,将项目ID作为参数接受。这也将确保它在viewDidLoad之前设置。因此,YPProjectViewController可以有一个方法,如:

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

  3. 关于自定义容器调用的两个不相关的观察结果:

    1. 当您致电addChildViewController时,会为您拨打willMoveToParentViewController。因此,您应该删除对willMoveToParentViewController的调用。请参阅documentation for that method

    2. 您甚至可能希望完全停用这些自定义容器调用,只需将YPTabBarViewController作为UITabBarController的子类,而不是UIViewController。这完全消除了对自定义容器调用的需要。显然,如果您对自定义容器有其他需求,那么请随意,但在此代码示例中它是多余的。