1

我在这里遇到了一个非常有趣的问题。我的 iPhone 应用程序在 AppDelegate 中有一个 UITabbarController 作为 rootViewController。

如果是第一次打开app,基本都要配置好。为此,我创建了一个 UINavigationController 并告诉 tabbarController 以模态方式呈现它:

firstRun = [[firstRunViewController alloc] init];
navCtrl = [[UINavigationController alloc] initWithRootViewController:firstRun];
[[self tabBarController] presentModalViewController:navCtrl animated:NO];

配置完成后,我想摆脱 firstRunViewController。我经常使用这种技术,使用-dismissModalViewControllerAnimated:.

但在这个星座中这是行不通的。我将哪个控制器称为解雇并不重要。我通过 tabbarController、rootViewController、当前活动的 viewController、原因 self 和其他几个控制器进行了尝试。

每次我打电话-dismissModalViewControllerAnimated:都会遇到这个异常:

'UIViewControllerHierarchyInconsistency', reason: 'presentedViewController for controller is itself on dismiss for: <UINavigationController:…

有人可以帮忙吗?在此先感谢,致以诚挚的问候,朱利安

编辑 在我的 AppDelegate 中,我使用 UITabbarController 作为主窗口的 rootViewController:

self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];

然后我创建一个 UINavigationController 并告诉 UITabbarController 呈现 modalViewController:

UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:firstRun];
[[self tabBarController] presentModalViewController:navCtrl animated:NO];

当我现在在 firstViewController 上调用 -dismissModalViewControllerAnimated: 时,我收到了上面的错误。

4

3 回答 3

1

在我看来,您正在滥用 UITabbarController。这个类,即使是 UIViewController 的子类,并没有真正使用很多 UIViewController 基础结构。

你想要的是对你现在拥有的东西的轻微扩展。在您的 appDelegate 中创建一个新的 UIViewController 子类,并将其作为单个对象添加到数组中,并将 tabBar 的 viewControllers 设置为该数组。将您的子类的 hidesBottomBarWhenPushed 设置为 YES,以便在标签栏可见时将其隐藏。

现在您的应用程序将启动,您的 UIViewController 子类将成为最前面的视图。您可以使这个视图成为您想要以模态方式呈现的视图,或者您可以使用某种动画从您的子类中呈现该视图。哦,如果你使用启动视图作为你的子类的背景图像,你真的可以让它平滑过渡——我现在就这样做。

当您的模态视图完成后,您可以实例化您想要显示的任何视图,并将 UITabBarController 设置为将这些视图与 tabBarController.viewControllers(或动画版本)一起使用。噗,你的 UIViewController 会被替换(并且在 ARC 下会消失)。

于 2012-07-15T15:04:02.190 回答
1

我没有机会检验我的假设,但我怀疑这个问题可能取决于您过早呈现模态视图这一事实,即过早意味着在主窗口有机会设置选项卡之前酒吧控制器。因此,我建议进行以下更改:

  1. 创建一个方法来实例化您的导航控制器:

    - (void)initializeAndPresentNavigationController {
      UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:firstRun];
      [[self tabBarController] presentModalViewController:navCtrl animated:NO];
    }
    
  2. 不是直接从 appDidFinishLaunching 显示导航控制器,而是异步调用上述方法:

    [self performSelector:@selector(initializeAndPresentNavigationController) withObject:nil afterDelay:0.0];
    

这里调用方法的技巧就像我在 2 中所做的那样,调用initializeAndPresentNavigationController将简单地推送到主循环上,并在您的应用程序有可能构建其初始 UI 后执行。

希望对你有效。

于 2012-07-15T18:37:09.070 回答
1

我终于自己找到了答案!我只是看不到树木的树林!我现在很开心!:)

我做了非常愚蠢的事情:在设置 viewControllers 的最后一个 viewController 中,我必须根据用户是否是管理员来更改 tabars viewControllers。所以我做了:

appDelegate.tabBarController.viewControllers = [NSArray arrayWithObjects:appDelegate.readState,
                                                appDelegate.navCtrl,
                                                appDelegate.settings, nil];

您可以看到我正在将 AppDelegate 的“navCtrl”添加到选项卡栏的 viewControllers。所以我试图关闭我刚刚添加到 parentViewControllers (UITabbarController) 子控制器的 viewController。

不建议在同一时刻忽略我想展示的东西!:))

于 2012-07-17T19:26:24.747 回答