My application has a setup screen that should be presented modally on the root view controller if certain conditions are met.
I have looked around on SO and the internet and the closest answer so far to how to go about doing this is here:
AppDelegate, rootViewController and presentViewController
There are 2 problems with this approach however:
- In iOS 8, doing it this way makes a log appear in the console, which doesn't seem to be an error, but is probably not good nonetheless:
Unbalanced calls to begin/end appearance transitions for UITabBarController: 0x7fe20058d570.
- The root view controller actually shows up very briefly when the app launches, and then fades into the presented view controller (even though I explicitly call
animated:NO
on mypresentViewController
method).
I understand that I can set my root controller dynamically in applicationDidFinishLaunchingWithOptions:
but I specifically want to present the setup screen modally, so that when the user is done with it, it dismisses and the true first view of the application is revealed. This is to say, I don't want to dynamically change my root view controller to my setup screen, and present my app experience modally when the user is done setting up.
Presenting the view controller on my root view controller viewDidLoad
method also leads to a noticeable blink of the UI when the app is launched for the first time.
Is it possible to programmatically present a view controller modally, before the application has rendered anything so that the first view in place is the modal view controller?
UPDATE: Thank you for the comments, adding my current code as suggested:
In my AppDelegate.m
:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:[storyboard instantiateViewControllerWithIdentifier:@"setupViewController"] animated:NO completion:NULL];
return YES;
}
This does what I need except for the fact that it briefly shows the window's root view controller for a second when the application launches, then fades the setupViewController, which I find odd given that I am presenting it without animation and fading is not how a modal view controller is presented anyway.
The only thing that has gotten me close is manually adding the view in the root view controller's view did load method like so:
- (void)viewDidLoad
{
[self.view addSubview:setupViewController.view];
[self addChildViewController:setupViewController];
}
The problem with this approach is that I can no longer "natively" dismiss the setupViewController, and will now need to deal with the view hierarchy and animated it out myself, which is fine if it's the only solution, but I was hoping there was a sanctioned way of adding a view controller modally without animation before the root view controller displays.
UPDATE 2: After trying a lot of things out and waiting for an answer for 2 months, this question proposes the most creative solution:
iOS Present modal view controller on startup without flash
I guess it's time to accept that it's just not possible to present a view modally without animation before the root view controller appears. However the suggestion in that thread is to create an instance of your Launch Screen and leave that on for longer than default until the modal view controller has had a chance to present itself.