8

我正在构建一个使用多种类型屏幕的应用程序——所有这些都保证了它们自己的自定义视图控制器。window通过使用我的应用程序委托中的方法重新分配 main ,我成功地在视图控制器及其相关视图之间切换,rootViewController如下所示:

- (void)changeRootViewController:(NSString *)controllerName
{
    if (controllerName == @"book") {
        rootViewController = (UIViewController *)[[BookViewController alloc] init];
        [self.window setRootViewController:rootViewController];
    } else if (controllerName == @"something_else") {
        // Use a different VC as roowViewController
    }
}

然而,我这样做的方式似乎不是最佳实践。我也不想使用 aUINavigationController或 aUITabBarController作为rootViewController。这是错误的方法吗?如果是这样,我应该如何以不同的方式处理这个问题?

我以为这会在某个地方被覆盖,但是(我觉得好像)我已经用谷歌搜索了它,寻找相关问题等。抱歉,如果我错过了什么!

4

2 回答 2

10

一种很好的方法是使用 iOS5+ 的 UIViewController 拥有子 UIViewControllers 的能力(它被称为视图控制器包含)。在我观看 WWDC 视频之前,我确实很难弄清楚如何做到这一点,该视频详细解释了这一点。

简而言之,它允许您创建自己的父视图控制器,该控制器拥有一系列子视图控制器。这个单一的父视图控制器可以(并且可能应该,除非你正在做一些非常花哨的东西:P)作为你的应用程序窗口的根视图控制器。这种让单个视图控制器充当父视图控制器的方法(并促进子视图控制器的添加、删除和转换)让人想起 UINavigationController 所做的事情(这是 Apple 的意图)。现在你可以创建你自己的类似 UINavigationController 的父视图控制器,但是有完全不同的过渡动画和 UI。

例如,在父视图控制器中,在 viewDidLoad 中,我添加了第一个子控制器,如下所示:

self.currentlyDisplayedChildViewController = [[TheFirstViewController alloc] init];
[self addChildViewController:self.currentlyDisplayedChildViewController];
[self.view addSubview:self.currentlyDisplayedChildViewController.view];
[self.currentlyDisplayedChildViewController didMoveToParentViewController:self];

然后我会有一个函数来转换到下一个子视图控制器(注意:这个函数属于父视图控制器——将作为你的 UINavigationController 的视图控制器)

- (void)transitionToViewController:(UIViewController *)nextChildViewController
{
    [self addChildViewController:nextChildViewController];
    __weak TheParentViewController *me = self;
    [self transitionFromViewController:self.currentlyDisplayedChildViewController
                      toViewController:nextChildViewController
                              duration:1.0f
                               options:UIViewAnimationOptionTransitionFlipFromLeft
                            animations:nil
                            completion:^(BOOL finished)
                            {
                                [nextChildViewController didMoveToParentViewController:self];
                                [me.currentlyDisplayedChildViewController willMoveToParentViewController:nil];
                                [me.currentlyDisplayedChildViewController removeFromParentViewController];
                                me.currentlyDisplayedChildViewController = nextChildViewController;
                            }];
}

一件非常好的事情是您可以使用所有标准 UIViewAnimationTransition 选项(或在动画块中定义您自己的自定义动画。此外,任何方向旋转事件都会自动从父视图控制器转发到子视图控制器。这就是其中之一自己进行自定义根视图控制器操作的最棘手的问题。

我建议看一下标题为“实现 UIViewController Containment”的 WWDC2011 视频。

于 2012-12-15T05:15:47.350 回答
3

它不是一个糟糕的解决方案。您基本上将一个视图设置为根视图。当您需要另一个 UIViewController 时,您可以设置另一个。只是要小心泄漏...

  • 使用保留创建 rootViewController 作为类的属性。
  • 在这之前:

rootViewController = (UIViewController *)[[BookViewController alloc] init];

添加这个:

if(rootViewController){
    self.rootViewController=nil;
}

}

所以你释放前一个。

编辑 1:一件事:我在这里的解释是基于您不想使用 UINavigationController 的事实。

于 2011-07-25T15:13:53.463 回答