In our storyboard we have multiple UINavigationController
stacks. For example, the LoginViewController
stack is completely separate from the SWRevealViewController
stack.
What's the best practice for switching between them? When I press the logout button (the logout button is on the SWRevealController
stack) and then try to present the LoginViewController stack, I get an error like this:
Warning: Attempt to present LoginViewController on SWRevealViewController whose view is not in the window hierarchy!
Even though I'm specifically setting self.window.rootViewController
to the Login View Controller's UINavigationController
in App Delegate like this:
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];
Is there a way I can "dismiss" the current UINavigationController
stack and use a new one? Or maybe I shouldn't be calling this code in my app delegate?
I had not played with SWRevealViewController
before your question, so my previous response was a little more generic. I've created a sample app here that does its best to throw around as many navigation stacks as possible; I'm sure I've covered your use case.
A few things I'll draw your attention to:
The "main flow" from my previous answer is right smack in the middle of the storyboard; that should help orient you.
SWRevealViewController.m
can be used in conjunction with Storyboards and has a very clever hack to do so, but the documentation for it is buried in the implementation. It took me a while to figure out what the hell was happening, but my example app illustrates the usage (two segues, one for "front" and the other for "back", could have a third for "right").
The app's main flow gets completely swapped out for the alternate flow. This is by design of SWRevealViewController
. You are essentially switching to an entirely new app.
All sub-flows that are presented modally disrupt the flow.
The author of SWRevealViewController
has not provided UIStoryboardSegue
subclasses for the replacement of front, rear, and right view controllers. This would be trivial to implement, but I've elected to do the swapping manually in FHKSettingsViewController
's implementation.
I repeated code and made dinky classes to make sure what I was doing was obvious.
You should wait to call presentViewController until viewDidAppear on rootViewController.
See here for more discussion: whose view is not in the window hierarchy
Edit:
call presentViewController
from your UINavigationcontroller's
rootviewController in viewDidAppear:
method
-(void)viewDidAppear:(BOOL)animated {
LoginViewController *loginVC = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[self presentViewController:loginVC animated:NO completion:nil];
[super viewDidAppear:YES];
}