在Storyboard中切换UINavigationController堆栈的最佳实践

时间:2013-11-08 06:04:20

标签: ios uinavigationcontroller storyboard

在我们的故事板中,我们有多个UINavigationController堆栈。例如,LoginViewController堆栈与SWRevealViewController堆栈完全分开。

在它们之间切换的最佳做法是什么?当我按下注销按钮(注销按钮在SWRevealController堆栈上)然后尝试呈现LoginViewController堆栈时,我收到如下错误:

Warning: Attempt to present LoginViewController on SWRevealViewController whose view is not in the window hierarchy!

即使我专门将self.window.rootViewController设置为App Delegate中的Login View Controller UINavigationController,如下所示:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Spitfire" bundle:nil];
UINavigationController *nav = [storyboard instantiateViewControllerWithIdentifier:@"LoginNavigationController"];
LoginViewController *loginVC = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];

self.window.rootViewController = nav;
[nav presentViewController:loginVC animated:NO completion:nil];    

有没有办法可以“解雇”当前的UINavigationController堆栈并使用新堆栈?或者也许我不应该在我的应用代理中调用此代码?

3 个答案:

答案 0 :(得分:5)

我在你的问题之前没有使用过SWRevealViewController,所以我以前的回答更加通用。我已经创建了一个示例应用程序here,尽可能多地使用尽可能多的导航堆栈;我确定我已经覆盖了你的用例。

我会引起你注意的一些事情:

  1. 我之前回答的“主要流程”正好在故事板的中间;这应该有助于确定你的方向。

  2. SWRevealViewController.m可以与Storyboards一起使用,并且有一个非常聪明的黑客,但它的文档是buried in the implementation。我花了一段时间来弄清楚到底发生了什么,但我的示例应用程序说明了用法(两个segues,一个用于“front”,另一个用于“back”,可能有三个用于“right”)。

  3. 应用程序的主流完全换出备用流程。这是SWRevealViewController的设计。您基本上切换到一个全新的应用程序。

  4. 以模拟方式显示的所有子流扰乱流程。

  5. SWRevealViewController的作者未提供UIStoryboardSegue子类来替换前视图,后视图和右视图控制器。这实现起来很简单,但我选择在FHKSettingsViewController的实现中手动进行交换。

  6. 我重复了一些代码并制作了很少的课程,以确保我所做的事情是显而易见的。

答案 1 :(得分:0)

你应该等到调用presentViewController直到rootViewController上的viewDidAppear。

有关详情,请参阅此处:whose view is not in the window hierarchy

答案 2 :(得分:0)

编辑:

presentViewController方法中的UINavigationcontroller's rootviewController中调用viewDidAppear:

-(void)viewDidAppear:(BOOL)animated {

   LoginViewController *loginVC = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
   [self presentViewController:loginVC animated:NO completion:nil];
   [super viewDidAppear:YES];
}