视图控制器如何在UINavigationController中“嵌入”自身 - 特别是当包含在容器视图控制器中时

时间:2014-03-27 09:27:53

标签: ios iphone objective-c uiviewcontroller uinavigationcontroller

很抱歉长篇故事 -

我对导航控制器层次结构的正确使用存在一些问题。

每个UIViewController都有一个属性self.navigationController

但并非每个视图控制器都来自导航控制器 - 因此该属性可能为零。

更多 -

一些视图控制器希望能够:

[self.navigationController presentViewController:nextViewController];

但如果它本身未包含在导航控制器层次结构中,则该表达式将不执行任何操作。

因此实体视图控制器可以测试它是否嵌入在导航控制器中:

if (self.navigationController == nil)
{
  // create a UINavigationController with a root view controller - the next view controller
  UINavigationController *nav = [UINavigationController alloc] initWithRootViewController:nextViewController];
  [self presentViewController:nav];
}

但这可能会破坏目的 - 因为如果呈现视图控制器不在导航控制器中 - 为什么下一个视图控制器必然需要在导航控制器中。为什么当前的视图控制器不会这样做:

[self presentViewController:nextViewController];

并跳过导航控制器创建?

在这些确切的方面 - 我面临的另一个问题 -

某些视图控制器希望从UINavigationController -

中呈现

因为他们在提供的导航控制器栏中设置了导航项 - 工具栏项目,标题等。

如果由于某种原因他们self.navigationController == nil - 他们怎么能“把自己”放在导航控制器中以确保他们可以访问那些预期的元素?

关于导航控制器内部的容器视图控制器问题:

如果你看一下iOS音乐应用程序 - 你可以看到嵌入UITabBarController内部的UIViewNavigationController - 每个标签都是一个单独的视图控制器 - 每个都可以“推”和“pop”视图控制器本身。

我需要实现类似的效果(但使用不同的布局),所以我创建了一个内部带有UITabBar视图的容器视图控制器。

然后我在容器视图控制器

中创建了一个演示文稿container视图

这个容器是每个子视图控制器的视图所在的位置。(那些是'父视图控制器'的'子视图控制器') - 这有点绕口令,我为此道歉。

选项卡栏切换 - 父视图控制器交换该容器中的可见视图控制器。

现在每个视图控制器都非常通用 - 他们不知道它们的包含但是期望有一个UINavigationController变量设置(非零)以设置标题 - 按钮 - 导航项等。< / p>

通用黑匣子视图控制器如何“呈现”自身(嵌入自身)在导航控制器中 -

容器视图控制器如何设置子视图控制器的navigationController属性?

1 个答案:

答案 0 :(得分:0)

我有一个应用程序,它有一个占位符(self.mainView),可以根据选项卡选项放置viewControllers。其中一些需要NavigationController,其他人则不需要。如果self.navigationController == nil,你可以随时进行测试并相应地工作。

以下是一些示例代码,用于将viewController显示到可以帮助您的占位符中。

if (self.currentController) {
    [self.currentController willMoveToParentViewController:nil];
    [[self.currentController view] removeFromSuperview];
    [self.currentController removeFromParentViewController];
    self.currentController = nil;
}


switch (tag) {
    case 0:
        self.currentController = [self.storyboard instantiateViewControllerWithIdentifier:@"AboutViewController"];
        break;

    case 1: {
        UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"EventsViewController"]];
        self.currentController = controller;
    }
        break;
}


if (self.currentController) {
    [self addChildViewController:self.currentController];
    [self.mainView addSubview:self.currentController.view];
    [self.currentController didMoveToParentViewController:self];
    [self adjustMainView];
    [self.view layoutIfNeeded];
}