在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
,所以我之前的回复更加通用。 我在这里创建了一个示例应用程序,尽可能多地使用尽可能多的导航堆栈; 我确定我已经覆盖了你的用例。
我会引起你注意的一些事情:
-
我之前的回答中的“主要流程”恰好位于故事板的中间; 这应该有助于你的方向。
-
SWRevealViewController.m
可以与Storyboards一起使用,并且有一个非常聪明的黑客方法,但它的文档隐藏在实现中 。 我花了一段时间来弄清楚到底发生了什么,但我的示例应用程序说明了用法(两个segues,一个用于“front”,另一个用于“back”,可能有三个用于“right”)。 -
应用程序的主流程完全换掉备用流程。 这是
SWRevealViewController
的设计。 你本质上是转向一个全新的应用程序。 -
以模态方式呈现的所有子流都会破坏流程。
-
SWRevealViewController
的作者没有提供UIStoryboardSegue
子类来替换前视图控制器,后视图控制器和右视图控制器。 这对于实现来说是微不足道的,但我选择在FHKSettingsViewController
的实现中手动进行交换。 -
我重复了代码并制作了一些极简的课程,以确保我所做的事情是显而易见的。
你应该等到调用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]; }