How to avoid “whose view is not in the window hierarchy” error when presenting a UIViewController

Screen Shot 2015-09-23 at 10.19.53

When you present a view controller from another one, iOS will do it just fine but may complain with something along the lines of the following error message:

Warning: Attempt to present <SecondViewController: 0x7fb54b523240> on <ViewController: 0x7fb54b61e7f0> whose view is not in the window hierarchy!

This can happen when you present the second view controller with a simple method like this:

[self presentViewController:secondView animated:YES completion:nil];

What iOS has a problem with is that “self” may not be the top most view controller in the window hierarchy, from which ordinarily another view controller should be presented. Think of presenting view controllers using a navigation controller: “self” doesn’t do it; instead the navigation controller must do it, being higher up the hierarchy than the current view controller.

So rather than present from “self”, we should be presenting from the top most view controller in our keyed window, like so:

UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
[top presentViewController:secondView animated:YES completion: nil];

To make sure you’re always presenting from the top most view controller, you can make use of a small helper method courtesy of akr and Darshan Kunjadiya. It goes like this:

- (UIViewController*) topMostController {
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}




4 thoughts on “How to avoid “whose view is not in the window hierarchy” error when presenting a UIViewController

  1. I tried using this solution , but the error persists.

    I am working with conditions for each of my screens , and when it first enters any of the screens if I sign , the problem is that the error entrarar another condition for the second time appears to me and shows me the screen , someone knows what this is? I leave part of the code so that it can be viewed in more detail .

    int uno= 23118, dos=40622, tres=64254  ;
        
        
        
        printf(" %d %d %d  ", b1,b2,b3);
        
        
        if ([beacons.firstObject.major intValue] == uno &amp;&amp; b1 == 0) {
            
            b1=2;
            b2=0;
            b3=0;
            
            unoViewController *viewcontroller = [self.storyboard instantiateViewControllerWithIdentifier:@"be1"];
           
            UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
            [top presentViewController: viewcontroller animated:YES completion: nil];
            
           
        }
        
        
        else if ([beacons.firstObject.major intValue] == dos &amp;&amp; b2 == 0) {
            
            b1=0;
            b2=2;
            b3=0;
            
          dosViewController *viewcontroller = [self.storyboard instantiateViewControllerWithIdentifier:@"be2"];
            
            UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
            [top presentViewController: viewcontroller animated:YES completion: nil];
    
            
            
            
        }
        
        
        else if ([beacons.firstObject.major intValue] == tres &amp;&amp; b3 == 0) {
            
            b1=0;
            b2=0;
            b3=2;
            
            tresViewController *viewcontroller = [self.storyboard instantiateViewControllerWithIdentifier:@"be3"];
            
            UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
            [top presentViewController: viewcontroller animated:YES completion: nil];
    
            
            
        }
        
        else
            
        {
            printf("Salio del rango");
        }
    

Leave a Reply