Manual modal segue does not work, View Controller is not in the window hierarchy?

blundin picture blundin · Mar 25, 2013 · Viewed 9k times · Source

I've been searching the web and Stack Overflow for hours and I cannot resolve this issue. here's hoping you all see my mistake, because I just can't find it.

I have a simple storyboard-based application I just started. The initial ViewController is an instance of UITabBarController with the two dummy ViewControllers from the template. Upon start up I need to check if the device is logged into an external service. If not I will show a modal ViewController that will allow the user to authenticate, if the device is authenticated then I will just show the FirstViewController.

The following steps are everything I have done since creating the project:

  1. Create the AuthenticateViewController scene on the Storyboard
  2. Create code files for AuthenticateViewController, and assign them to the corresponding scene
  3. Create code files for a UITabBarController subclass, and associate the initial UITabBarController scene to that new subclass
  4. Create a new segue on the storyboard from the UITabBarController scene to the AuthenticateViewController scene
  5. Manually call the segue from viewDidLoad in the UITabBarController subclass

When I run the application the modal segue does not fire, the first ViewController of the UITabBarController is shown, and I get the following output in XCode:

Warning: Attempt to present <AuthenticateViewController: 0x83c0c10> on <EPTabBarController: 0x83be600> whose view is not in the window hierarchy!

Relevant code below, in fact the only code I have added so far. Please let me know if screenshots or additional information would be useful. Thanks in advance for your help.

EPTabBarController, subclass of UITabBarController:

#import "EPTabBarController.h"
#import "AuthenticateViewController.h"

@interface EPTabBarController ()

@end

@implementation EPTabBarController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Answer

βhargavḯ picture βhargavḯ · Mar 25, 2013

The issue is inside

- (void)viewDidLoad
{
    [super viewDidLoad];    
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}

you are trying to present another view( AuthenticateViewController ) while your current view( EPTabBarController ) is not yet loaded in the window hierarchy.

So first let your EPTabBarController to get loaded in window hierarchy and then present AuthenticateViewController.

Give this a try

- (void)viewDidLoad 
{
    [super viewDidLoad];        
    [self performSelector:@selector(loadAuthenticateViewController) 
               withObject:nil 
               afterDelay:1.0];
}

-(void)loadAuthenticateViewController 
{
    [self performSegueWithIdentifier:@"authenticationSegue" sender:self];
}