View Controller Containment共享父对象

时间:2013-05-17 15:51:31

标签: ios objective-c cocoa-touch

我正在使用视图控制器包含,作为我的实现的一部分,子视图控制器需要禁用父视图控制器的导航控制器的条形按钮项。理论上,作为一个子视图控制器,我可以访问与父视图控制器相同的导航控制器(在我的上下文中)。

从调试开始,我可以看到self.navigationControllerself.parentViewController.navigationController设置为相同的地址。

例如:

NSLog(@"%@ - %@", self.navigationController, 
                  self.parentViewController.navigationController);

NSLog(@"%@ - %@", self.navigationItem, 
                  self.parentViewController.navigationItem);

NSLog(@"%@ - %@", self.navigationController.navigationItem, 
                  self.parentViewController.navigationController.navigationItem);

在以下控制台日志中导致:

<UINavigationController: 0xc482290> - <UINavigationController: 0xc482290>

<UINavigationItem: 0xa5f3620> - <UINavigationItem: 0xc482490>

<UINavigationItem: 0xa5f36e0> - <UINavigationItem: 0xa5f36e0>

结果

  • 导航控制器与预期相同(自我&gt; navController == self-&gt; parent-&gt; navController )。
  • 导航项目不同,这是预期的。每个视图控制器都有自己的导航项(self-&gt; navItem != self-&gt; parent-&gt; navItem )。
  • 从父视图控制器或子视图控制器访问导航控制器导航项是完全一样的(自我&gt; navController-&gt; navItem == self-&gt; 父级 - &GT; navController-&GT; navItem

所以我现在问:为什么没有使用以下代码禁用子视图控制器中的条形按钮项:

self.navigationController.navigationItem.rightBarButtonItem.enabled = NO;

这应该是以下内容的同义词(它可以按预期工作)给出共享地址:

self.parentViewController.navigationController.navigationItem.rightBarButtonItem.enabled = NO;

更新

我读的日志太快了。实际上,parentViewController和导航控制器有2个不同的导航项。我在这里的例子中错过了这个,因为内存地址非常接近: 0xa5f3620 != 0xa5f36e0

2 个答案:

答案 0 :(得分:1)

基本上问题是导航控制器更新条形按钮项的方式,基本上每当顶级子项被更改时按钮都会更新。 对于右侧栏按钮项,如果新的顶级子项具有自己的栏按钮项,则导航控制器将选择现有的项,如果不是,则不显示任何内容。 因此,在您的情况下,parrentViewController已经有一个未被禁用的navigationItem.rightBarButonItem,通过调用self.navigationController.navigationItem.rightBarButtonItem.enabled = NO;您正在禁用子项的nabigationItem.rightBarButtonItem而您无法看到这一点,因为更新仅在顶级时进行孩子被改变了,这不是你的情况。

因此,为了禁用parentViewController右键,你应该这样做: self.parentViewController.navigationItem.rightBarButtonItem.enabled = NO

有关导航栏按钮更新的更多详细信息,请查看有关Updating Navigation Bar Items

的Apple文档

答案 1 :(得分:1)

UINavigationController有它自己的navigationItem(就像任何其他的UIViewController一样),只有当你把它推到另一个UINavigationController的堆栈上时才会发挥作用。

一般情况下,你不会将一个UINavigationController推送到另一个上,因此操纵self.navigationController.navigationItem是没有意义的。

编辑:

要检查......我刚才说:

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    UINavigationItem *myNavControllersItem = self.navigationController.navigationItem;
    UINavigationItem *myItem = self.navigationItem;
    NSLog(@"%@ - %@", myNavControllersItem, myItem);
}

到我正在推送到NavController的VC并获取:

<UINavigationItem: 0x1ed0c170> - <UINavigationItem: 0x1ed46330>

此外,如果我添加:

self.navigationItem.rightBarButtonItem.enabled = NO;viewDidAppear右侧按钮被禁用。

如果我添加:

self.navigationController.navigationItem.rightBarButtonItem.enabled = NO;它没有。