View frame changes between viewWillAppear and viewDidAppear
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If a view's frame changes between viewWillAppear and viewDidAppear, the usual reason is that Auto Layout and container transitions are still settling the final geometry. In other words, viewWillAppear happens before the view is fully onscreen and before the final post-layout frame is guaranteed.
Why the Frame Can Change
Several things can still affect layout after viewWillAppear runs:
- Auto Layout constraint resolution
- navigation bar or tab bar adjustments
- safe area inset changes
- container controller transitions
- animated presentations
That means code like this can print different values at different lifecycle points:
The later callback often reflects the final onscreen geometry more accurately.
The Better Layout Hook: viewDidLayoutSubviews
If your goal is "I need the final laid-out size," viewDidLayoutSubviews is usually the better lifecycle hook than viewDidAppear.
This method runs after Auto Layout has laid out the subviews, so it is the right place for frame-dependent layout adjustments.
viewWillAppear Versus viewDidAppear
Use viewWillAppear for:
- refreshing content
- updating navigation items
- configuring state before the screen becomes visible
Use viewDidAppear for:
- starting animations that require visible presentation
- kicking off work that depends on the view actually being onscreen
- final checks where transition completion matters
If the issue is specifically geometry, viewDidLayoutSubviews is often more precise than either.
Example: Positioning a Subview Based on Final Size
Suppose you want to size a banner to match the safe area width:
Doing this in viewWillAppear is riskier because safe-area values and final bounds may still change.
Container Controllers Make This More Noticeable
When a controller is inside:
- a
UINavigationController - a
UITabBarController - a custom container
- a sheet or popover presentation
the final frame is even more likely to shift after viewWillAppear. Bars, insets, and transition coordinators can all alter the effective visible area.
That is why layout-sensitive code often behaves inconsistently when moved between different presentation styles.
Frames Versus Bounds
Another source of confusion is looking at frame when bounds is really the value you care about.
- '
frameis the view's rectangle in its superview's coordinate system' - '
boundsis the view's own internal coordinate rectangle'
For many internal layout calculations, bounds is the more stable and relevant measurement:
If you are laying out subviews inside self.view, prefer bounds unless you explicitly need superview coordinates.
This distinction becomes even more important if transforms or nontrivial container hierarchies are involved, because frame can reflect relationships outside the view's own coordinate system.
Common Pitfalls
The biggest mistake is doing frame-dependent work in viewWillAppear and assuming the numbers are final. That assumption can break as soon as Auto Layout, safe areas, or animated presentation enters the picture.
Another issue is using viewDidAppear for one-time frame setup when viewDidLayoutSubviews is the real layout callback. viewDidAppear runs after visibility, not specifically after every layout pass.
Finally, avoid hard-coding frame math if constraints can express the layout cleanly. In many modern UIKit screens, the best answer is not "pick the right lifecycle method" but "let Auto Layout own the geometry."
Summary
- Frame changes between
viewWillAppearandviewDidAppearusually come from layout and transition timing. - '
viewWillAppearis not a guarantee that final geometry has settled.' - '
viewDidLayoutSubviewsis usually the best place for frame-dependent layout code.' - '
viewDidAppearis better for visible-state actions than for pure layout.' - Prefer
boundsfor internal subview layout and Auto Layout when possible.

