0

I have a Storyboard application that the root view controller is a UITableViewController.

Sometimes when I launch the application I need to present a view controller (that doesn't need a nib or anything). This is how I'm trying to do that:

In my UIApplicationDelegate application:application didFinishLaunchingWithOptions::

SplashViewController * splashViewController = [[SplashViewController alloc] init];
splashViewController.semaphore = semaphore;
[self.window.rootViewController presentViewController:splashViewController animated:NO completion:nil];

The problem is, in this moment the UITabBarController is not yet in the view hierarchy, so I get this warning:

Warning: Attempt to present <SplashViewController: 0xa786a10> on <UITabBarController: 0xb35d830> whose view is not in the window hierarchy!

Moving this code from the AppDelegate to the viewDidLoad of the first view controller of the UITableViewController doesn't seen to be right, as I would need to create some properties in my AppDelegate just to make my first view controller build that view. This logic doesn't fit there.

What would be the proper way to present this view controller?

Marco Pompei
  • 1,080
  • 1
  • 8
  • 18
  • Why do you need to create those properties in the appDelegate rather than in viewDidLoad of the root view controller? – rdelmar Dec 28 '12 at 20:32

2 Answers2

3

Before you can present a view controller here, the window must be key and visible. You can accomplish this by doing the following:

[self.window makeKeyAndVisible];

So you're full code should look something like this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self.window makeKeyAndVisible];

    SplashViewController * splashViewController = [[SplashViewController alloc] init];
    splashViewController.semaphore = semaphore;
    [self.window.rootViewController presentViewController:viewController animated:NO completion:nil];

    return YES;
}
kylef
  • 1,066
  • 1
  • 8
  • 11
0

One way to do it could be to have a delegate callback from your rootViewController to the AppDelegate.

  • declare a delegate protocol in UITableViewController, something like

    - (void)rootViewHasLoaded;
    

Set you App Delegate as the delegate for UITableViewController (could do this in the storyboard)

Implement the delegate method in App Delegate, and in that method put your SplashViewController code

- (void)rootViewHasLoaded
{
    SplashViewController * splashViewController = [[SplashViewController alloc] init];
    splashViewController.semaphore = semaphore;
    [self.window.rootViewController presentViewController:splashViewController 
                                                 animated:NO 
                                               completion:nil];
}

Call the delegate method from an appropriate place in your rootViewController / UITableViewController (probably viewDidLoad or viewWillAppear)

foundry
  • 31,615
  • 9
  • 90
  • 125