Warning Attempt to present on whose view is not in the window hierarchy - swift
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
This UIKit warning appears when a view controller tries to present another controller before it is actually on screen, or after it has stopped being the active presenter. The code often works sometimes and fails only under timing changes, which is why the warning is so common around startup flows, async callbacks, and navigation transitions. The fix is not to suppress the warning. The fix is to present from the currently visible controller at the correct lifecycle moment.
What the Warning Really Means
When you call present(_:animated:completion:), UIKit expects the presenting controller's view to be attached to a window and actively participating in the visible hierarchy. If that is not true, UIKit warns that the presentation request is invalid.
Typical causes:
- Presenting from
viewDidLoad. - Presenting from a controller that has already been dismissed or covered.
- Presenting after an async callback without rechecking the current UI state.
- Presenting from a child controller when the container should be doing it.
The message is really saying: "the presenter you chose is not the controller currently able to present UI."
Do Not Present in viewDidLoad
viewDidLoad is too early for modal presentation because the view may exist without being attached to a window yet.
This is a common mistake:
Move the presentation to a point where the controller is actually visible, usually viewDidAppear.
The guard avoids repeated presentation every time the screen reappears.
Recheck State After Async Work
Another common source is an async callback that finishes after the original screen is no longer active. Before presenting, verify that the controller still belongs to a window and is not already presenting something else.
That check matters because network completions and permission callbacks often outlive the screen that started them.
Present from the Topmost Visible Controller
In apps with tab bars, navigation controllers, or custom containers, the controller that owns the business logic may not be the one that should present. A small helper can locate the currently visible presenter.
Used carefully, that can prevent presenting from a controller that is technically alive but no longer the active UI surface.
Keep Presentation on the Main Thread
UIKit presentation must happen on the main thread. If a background completion block tries to present directly, the timing and behavior become unreliable even if the hierarchy is otherwise valid.
When in doubt, hop back to the main queue before touching presentation code.
Debug the UI Flow, Not Just the Line That Warns
This warning is often the end result of an earlier navigation mistake. Ask:
- Which controller is actually visible right now.
- Whether a dismissal or push is still in progress.
- Whether the callback that presents UI belongs to the current screen.
That mindset is more useful than adding delays until the warning disappears temporarily.
Common Pitfalls
- Presenting from
viewDidLoador another lifecycle point before the view is attached to a window. - Showing UI from an async callback after the original controller is no longer visible.
- Presenting from a controller buried inside a container when the topmost visible controller should present.
- Triggering UIKit presentation off the main thread.
- Adding arbitrary delays instead of fixing the actual presentation timing or presenter selection.
Summary
- The warning means the chosen presenter is not currently in the visible window hierarchy.
- '
viewDidAppearis usually safer thanviewDidLoadfor first-time modal presentation.' - Recheck
view.windowand existing presentation state after async callbacks. - In container-heavy apps, present from the topmost visible controller.
- Fix the UI flow itself rather than masking the problem with timing hacks.

