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

在我们的故事板中,我们有多个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堆栈并使用新的堆栈? 或者也许我不应该在我的应用代理中调用此代码?

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

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

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

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

  3. 应用程序的主流程完全换掉备用流程。 这是SWRevealViewController的设计。 你本质上是转向一个全新的应用程序。

  4. 以模态方式呈现的所有子流都会破坏流程。

  5. SWRevealViewController的作者没有提供UIStoryboardSegue子类来替换前视图控制器,后视图控制器和右视图控制器。 这对于实现来说是微不足道的,但我选择在FHKSettingsViewController的实现中手动进行交换。

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

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

有关更多讨论,请参见此处: 其视图不在窗口层次结构中

编辑:

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

 -(void)viewDidAppear:(BOOL)animated { LoginViewController *loginVC = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"]; [self presentViewController:loginVC animated:NO completion:nil]; [super viewDidAppear:YES]; }