UIViewController viewDidLoad vs. viewWillAppear What is the proper division of labor?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
viewDidLoad and viewWillAppear are both important UIKit lifecycle hooks, but they serve different jobs. A reliable rule is that viewDidLoad is for one-time setup after the view is created, while viewWillAppear is for work that must happen every time the screen is about to become visible.
What viewDidLoad Guarantees
viewDidLoad runs after the view hierarchy has been loaded into memory. For a typical view controller, that means outlets are connected and initial UI setup can happen safely. It usually runs once for the lifetime of that controller instance.
This makes it the right place for configuration that should not be repeated:
- Registering table or collection view cells
- Building constraints or styling views
- Setting delegates and data sources
- Starting one-time fetches for static data
- Subscribing to notifications that match the controller lifetime
Nothing in that block depends on the screen becoming visible right now. It is setup work, so viewDidLoad is the correct home.
What viewWillAppear Is For
viewWillAppear runs every time the controller is about to appear on screen, including after a push-pop navigation round trip. That makes it ideal for data refresh, selection updates, analytics events tied to exposure, and UI changes that may have become stale while the screen was hidden.
If the user edits the cart on another screen and navigates back, viewDidLoad will not run again. viewWillAppear will, which is why refreshing the total belongs there.
A Practical Division of Labor
A good mental model is "create once" versus "refresh often."
Use viewDidLoad for work that prepares the controller itself. Use viewWillAppear for work that prepares the visible state of the screen.
This combined example shows the difference:
Registering the cell and kicking off initial data loading fit viewDidLoad. Deselecting the previously tapped row each time the list reappears fits viewWillAppear.
When Another Lifecycle Method Is Better
Not every repeated task belongs in viewWillAppear. Some work is better in adjacent hooks:
- Use
viewDidAppearfor actions that require the view to be fully on screen, such as presenting a dialog or starting an animation that depends on final layout. - Use
viewWillDisappearorviewDidDisappearfor cleanup, pausing video, or stopping work tied to visibility. - Use
viewDidLayoutSubviewswhen you need correct final sizes before adjusting frames manually.
Choosing between these methods correctly makes controller behavior more predictable and easier to test.
Common Pitfalls
The classic mistake is putting expensive network calls in viewWillAppear without a reason. If the user navigates back and forth repeatedly, the request fires every time and can slow the app or duplicate server traffic.
Another mistake is assuming viewDidLoad runs whenever a view comes back on screen. It does not for the same controller instance, so anything that must refresh after navigation should not live there.
Developers also overload viewDidLoad with layout code that depends on final view size. At that point in the lifecycle, the layout may not be settled yet, so use a later hook if sizing matters.
Finally, avoid placing the same initialization in both methods. Repeating setup work such as observer registration can create duplicate callbacks and hard-to-debug behavior.
Summary
- '
viewDidLoadis for one-time controller and view setup.' - '
viewWillAppearis for state that should refresh each time the screen is about to show.' - If work depends on the view being fully visible, consider
viewDidAppearinstead. - Repeated network calls in
viewWillAppearare often a design smell unless the data truly must refresh. - A clean lifecycle split makes UIKit screens easier to reason about and maintain.

