Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy
Solution 1
Where are you calling this method from? I had an issue where I was attempting to present a modal view controller within the viewDidLoad
method. The solution for me was to move this call to the viewDidAppear:
method.
My presumption is that the view controller's view is not in the window's view hierarchy at the point that it has been loaded (when the viewDidLoad
message is sent), but it is in the window hierarchy after it has been presented (when the viewDidAppear:
message is sent).
Caution
If you do make a call to presentViewController:animated:completion:
in the viewDidAppear:
you may run into an issue whereby the modal view controller is always being presented whenever the view controller's view appears (which makes sense!) and so the modal view controller being presented will never go away...
Maybe this isn't the best place to present the modal view controller, or perhaps some additional state needs to be kept which allows the presenting view controller to decide whether or not it should present the modal view controller immediately.
Solution 2
Another potential cause:
I had this issue when I was accidentally presenting the same view controller twice. (Once with performSegueWithIdentifer:sender:
which was called when the button was pressed, and a second time with a segue connected directly to the button).
Effectively, two segues were firing at the same time, and I got the error: Attempt to present X on Y whose view is not in the window hierarchy!
Solution 3
viewWillLayoutSubviews
and viewDidLayoutSubviews
(iOS 5.0+) can be used for this purpose. They are called earlier than viewDidAppear.
Solution 4
For Display any subview to main view,Please use following code
UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (yourCurrentViewController.presentedViewController)
{
yourCurrentViewController = yourCurrentViewController.presentedViewController;
}
[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];
For Dismiss any subview from main view,Please use following code
UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (yourCurrentViewController.presentedViewController)
{
yourCurrentViewController = yourCurrentViewController.presentedViewController;
}
[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];
Solution 5
I also encountered this problem when I tried to present a UIViewController
in viewDidLoad
. James Bedford's answer worked, but my app showed the background first for 1 or 2 seconds.
After some research, I've found a way to solve this using the addChildViewController
.
- (void)viewDidLoad
{
...
[self.view addSubview: navigationViewController.view];
[self addChildViewController: navigationViewController];
...
}
![Kyle Goslan](https://i.stack.imgur.com/hYfF2.jpg?s=256&g=1)
Kyle Goslan
Updated on August 05, 2022Comments
-
Kyle Goslan almost 2 years
Just started using Xcode 4.5 and I got this error in the console:
Warning: Attempt to present < finishViewController: 0x1e56e0a0 > on < ViewController: 0x1ec3e000> whose view is not in the window hierarchy!
The view is still being presented and everything in the app is working fine. Is this something new in iOS 6?
This is the code I'm using to change between views:
UIStoryboard *storyboard = self.storyboard; finishViewController *finished = [storyboard instantiateViewControllerWithIdentifier:@"finishViewController"]; [self presentViewController:finished animated:NO completion:NULL];
-
Kyle Goslan almost 12 yearsThanks for the reply, I'll have a look at this and see if its whats causing it
-
Matt Mc almost 12 years@James you are correct, the view apparently is not in the hierarchy until after viewWillAppear has been resolved and once viewDidAppear has been called. If this were my question I would accept this answer ;)
-
Ali over 11 years@james Thanks. Using the ViewDidAppear solved the problem for me too. Makes sense.
-
Marc Endtricht over 11 yearsI wish I could upvote this twice. I just had this problem and came to the thread to find that I had already upvoted the last time I saw this.
-
Vincent over 11 yearsNote that when you change the VC in the viewDidAppear, this causes the execution of a segue, with Animation. Causes a flash/display of the background.
-
Jonny over 11 yearsStill they are used also in other occasions so I think they might be called several times in a view's "lifetime".
-
BootMaker about 11 yearsYes the trick is the viewWillAppear:(BOOL)animated as it's correct. One more important thing you have to call the super in the method, as [super viewDidAppear:animated]; without this it's not working.
-
foFox almost 11 yearsI think you are missing [navigationViewController didMoveToParentViewController:self]
-
tooluser almost 11 yearsIt's also not what the methods are for - as the name suggests. viewDidAppear is correct. Reading up on the view lifecycle is a good idea.
-
TMilligan over 10 yearsThis is the best solution. In my case, presenting in viewDidAppear causes a split second showing of the view controller before the modal is loaded, which is unacceptable.
-
surfrider about 10 yearsSame problem as Vincent mentioned. When presenting in ViewWillAppear, i have flickering presenting view controller before presented is appears.
-
Cruinh about 9 yearsWhile this might work now, there's no guarantee that Apple will change behavior and break this on you in the future. Then when you go back to look at your code to try and fix things again, you'll wonder why you were doing this seemingly unnecessary dispatch.
-
Dannie P about 9 yearsDispatch with 0 time has saved me quite a number of times already - sometimes things that just should logically work don't normally work without it. So just make comments for yourself and others on why you do unobvious things (not only such a dispatch) and you should be fine.
-
love2script12 about 9 yearsFor those who only looked at the upvoted answer, if you call if from AppDelegate, make sure it is called after [self.window makeKeyAndVisible]; Got this from another answer on this same page, but didn't want anyone to miss it
-
samouray about 9 yearsI had the same error, and your answer here helped me figure out what was going on, it was indeed this error, fixed it because of you sir, thank you, +1
-
Vlad almost 9 yearsI mean that video should be stopped/paused first.
-
MCB almost 9 yearsI deleted the old segue and connected VC to VC. Is there a way to connect the button to the storyBoard to the VC because that way just keeps erroring for me?
-
uplearned.com over 8 yearsThis answer worked the best for me when trying to display an alert. The alert wouldn't show when I put it into viewDidLoad and viewWillAppear.
-
igraczech over 8 yearsBTW to understand WHERE do I call this method from... it's the otherwise UI-less SDK library, that displays its own UI over your app in certain (undisclosed) case.
-
Omar N Shamali about 8 yearsactually this helped me, it led me after to this stackoverflow.com/questions/20746413/…
-
Logicsaurus Rex about 8 yearsI tried your code, along with foFox's suggestion, and when I go to remove it from it's parent, it won't go away. Lololol. Still stuck with no fix.
-
iamburak about 8 yearsI had same error, your answer solved my problem, thanks for your attention. Kind regards.
-
Eugene Braginets almost 8 yearsif you have storyboard you can use perform segue and main_queue dispatch_async(dispatch_get_main_queue()) { }
-
Michael Peterson almost 8 yearsYou are just hacking around the problem and not solving it.
-
user3000868 almost 8 yearsIn case anyone else has this problem, I had a similar problem using NSNotifications to trigger a method to presentViewController. I saw this solution but didn't think it applied to me as my methods weren't being called in viewDidLoad but then realized I had the addObserver for each notification in viewWillLoad --> 'view is not in the window hierarchy' error. When I moved the 'addObserver' to viewDidAppear, the errors disappeared.
-
Anton Tropashko over 7 yearsYou WILL crash and burn if anyone decides to embed you sdk in an app that has an extension. Pass a UIViewController to abuse into you sdk init method[s].
-
igraczech over 7 yearsYou're true Anton. This code was written when Extensions did not exist and SDK is not used in any of those yet. I've added a guard clause to skip this edge-case.
-
azizj over 7 yearsWorked for me also
-
Borzh about 7 yearslol, accidentally I also was creating two vc's: from button and performSegue, thanks for the tip!!!
-
Pokemon about 7 yearsWorks in Swift3.1
-
Iyyappan Ravi about 7 years@sunkehappy above two lines to be used in before presentviewcontroller, but its crashed why?
-
Vaibhav Limbani about 7 years@James Bedford Thanks ,you've saved my lot of time .Thank you very much :-)
-
shahtaj khalid almost 7 yearshow? can you elaborate? i'm facing the same problem. this is my code let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewController(withIdentifier: "SplashController") as UIViewController self.window?.rootViewController = initialViewControlleripad self.window?.makeKeyAndVisible()
-
Jaydeep Vyas over 6 years@James Bedford how to present view controller immediatly after the image is selected from gallery, because at the time uiimagepicker return me the image my controller is not appear
-
Samo about 6 yearsIn my case I was calling
present(viewController, animated: true, completion: nil)
inside a loop. -
rayepps about 6 yearsThis seems like a far more common issue that the many answers that have out voted yours. Unfortunate, this was extremely helpful
-
Teo Sartori over 5 yearsThis answer should be turned into an Xcode warning.
-
Mr Heelis about 5 yearsyes all well and good but what is the solution... i have a background worker thread going to a server and displaying storyboards left right and centre and the entire methodology is bogus.. it's awful.. what should be a breeze is utterly a joke because al I want to do int he background thread is :
wait
wait
decide
push screen to front
and it's IMPOSSIBLE is IOS???? -
Petey over 2 yearsThis was my issue. Thanks!