【问题标题】:View Controller Containment shared parent objects视图控制器包含共享父对象
【发布时间】:2013-05-12 20:55:10
【问题描述】:

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

通过调试我可以看到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>

结果

  • 导航控制器与预期相同(self->navController == self->parent->navController)。
  • 导航项不同,这是意料之中的。每个视图控制器都有自己的导航项(self->navItem != self->parent->navItem)。
  • 从父视图控制器或子视图控制器访问导航控制器导航项是相同的,正如预期的那样 (self->navController->navItem == self->parent->navController- >navItem)

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

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

鉴于它们的共享地址,这应该是以下(按预期工作)的同义词:

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

更新

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

【问题讨论】:

  • 您是否在同一方法中执行比较和分配?
  • navigationController.navigationItem 应该返回其堆栈中最顶层控制器的 navigationItem 还是它自己的 navigationItem?
  • @MikePollard 导航控制器从视图控制器类继承了这个,因为它与我假设它正在使用 topviewcontroller 的导航项的地址相同。

标签: ios objective-c cocoa-touch


【解决方案1】:

基本上问题在于导航控制器更新栏按钮项的方式,基本上,只要顶级子项发生更改,按钮就会更新。 对于右栏按钮项,如果新的顶级子项有它自己的栏按钮项,则导航控制器将选择现有的项,如果不是,则不会显示任何内容。 因此,在您的情况下,parrentViewController 已经有一个未禁用的 navigationItem.rightBarButonItem,通过调用 self.navigationController.navigationItem.rightBarButtonItem.enabled = NO; 您正在禁用孩子的 nabigationItem.rightBarButtonItem 并且您看不到这一点,因为只有在顶级孩子是改变了,这不是你的情况。

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

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

【讨论】:

    【解决方案2】:

    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 上:

    &lt;UINavigationItem: 0x1ed0c170&gt; - &lt;UINavigationItem: 0x1ed46330&gt;

    另外,如果我添加:

    self.navigationItem.rightBarButtonItem.enabled = NO;viewDidAppear 右键被禁用。

    如果我添加:

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

    【讨论】:

    • 谢谢,但是不管它是否看起来毫无意义,我会说使用导航的导航项,我能够更改屏幕上的可见项。建议在这种情况下,如果您访问导航控制器的导航项,它似乎会返回顶部视图控制器的导航项。
    • 嗯,我的测试不同意...奇怪。
    • 确实很有趣。所以确实导航控制器的导航项是别的东西,这确实有意义。此外,我认为我误解了我的日志关于一些非常重要的事情。确实如您所说 self.parentViewController.navigationItem != self.parentViewController.navigationController.navigationItem
    猜你喜欢
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多