viewWillAppear is a UIViewController method that UIKit calls every time before a screen becomes visible to the user. According to the Apple Developer Documentation, this method receives a boolean parameter animated indicating whether the transition occurs with animation. viewWillAppear is the primary place for updating data and synchronizing the screen state.
Key Takeaways
viewWillAppear is a UIViewController method that UIKit calls immediately before adding the View to the window hierarchy. At this point, the View already has its final dimensions after Auto Layout passes, but is not yet visible to the user — the transition animation either hasn't started or is in progress. The developer overrides this method to perform operations that should happen before each screen display.
Unlike viewDidLoad, which fires only once, viewWillAppear is called every time the screen is about to appear: during initial opening, when returning from a child controller, after dismissing a modal window, and when switching TabBar tabs. This makes it a key method for maintaining an up-to-date interface state.
The method accepts an animated parameter of type Bool, which is true if the screen appearance is accompanied by animation. This parameter is convenient to pass to NavigationBar and TabBar methods, which also have a similar parameter for consistent behavior.
The timing of the viewWillAppear call depends on the navigation type, but the general rule remains unchanged: the method fires before the View becomes visible. Let's consider the main scenarios.
After viewDidLoad, UIKit begins preparation for display: the View is added to the hierarchy, layout passes are triggered, and immediately before the transition animation begins, viewWillAppear is called. At this moment, the screen is not yet visible, but all subviews have correct sizes, and their content can be safely updated.
When the user taps the back button or programmatically calls popViewController, UIKit returns to the previous screen and calls its viewWillAppear. This is the main scenario for using viewWillAppear — updating a list after adding an item or synchronizing settings.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
After closing a modally presented controller, UIKit calls viewWillAppear on the controller that presented it. This scenario requires special attention if you use delegates or closures to pass data back — viewWillAppear ensures the screen updates after receiving the result.
TabBarController calls viewWillAppear on the selected tab's controller every time a switch occurs. If the tab displays dynamic data — exchange rates, notifications, user status — viewWillAppear is the ideal place to update them.
viewWillAppear solves several specific tasks that are impossible or suboptimal to perform in other methods. Let's look at the main ones.
The most common use of viewWillAppear is reloading a UITableView or UICollectionView every time the screen appears. If data could have changed on the previous screen (item added, status changed), calling reloadData in viewWillAppear guarantees the user sees up-to-date information.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
In viewWillAppear it is convenient to configure the NavigationBar appearance: hide or show it, change its color, set a large title. If different screens have different NavigationBar styles, viewWillAppear is the right place for these changes, since viewDidLoad is called only once.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(
false, animated: animated
)
navigationController?.navigationBar.prefersLargeTitles = true
tabBarController?.tabBar.isHidden = false
}
Notifications that only make sense when the screen is visible — keyboard notifications, content change notifications — are subscribed to in viewWillAppear and unsubscribed in viewDidDisappear. This prevents unnecessary handlers when the screen is not active and protects against memory leaks.
If the screen can be hidden by an app or minimized, viewWillAppear is a convenient place to restore the UI state: switching segments, restoring scroll position, resetting temporary changes. The user gets the screen in a predictable state each time it appears.
On screens displaying counters for unread messages, ratings, or notifications, viewWillAppear is the right place to update them. If the user could have changed the quantity on another screen, recalculation and updating of UITabBarItem.badgeValue or custom indicators are called here. This guarantees the user always sees current numbers regardless of how long they were on other screens.
Special attention should be given to working with collectionView: if the data on the screen is presented as a grid with cells containing counters or statuses, their update in viewWillAppear should be selective. Instead of a full reloadData, use reloadItemsAtIndexPaths for visible cells to avoid flickering and losing scroll position.
Understanding the difference between viewWillAppear and viewDidLoad is the foundation of proper UIViewController architecture. These methods have different call frequency, different context, and different purpose.
viewDidLoad is called once and is suitable for configuration that does not change over time: registering cells, setting delegates, initializing constants. viewWillAppear is called on each appearance and is suitable for operations that need to be repeated: updating data, configuring visible elements, synchronizing state.
| Characteristic | viewDidLoad | viewWillAppear |
|---|---|---|
| Frequency | Once | Every time on appearance |
| View visible | No | No (will become visible soon) |
| View dimensions | Not final | Final |
| Suitable for | One-time setup | Updates and synchronization |
| Animation | Not applicable | Animated parameter |
The golden rule: if an operation should execute only once — put it in viewDidLoad. If it should execute every time you return to the screen — put it in viewWillAppear.
Incorrect use of viewWillAppear can lead to performance issues, excessive updates, and inconsistent interface state. Let's look at the most common mistakes.
The first mistake — duplicating logic from viewDidLoad. If you register table cells in both viewDidLoad and viewWillAppear, registration will be performed multiple times, although one-time setup is sufficient. Move all one-time configurations to viewDidLoad.
The second mistake — unconditional reloadData on every appearance. If data hasn't changed, reloading the table causes unnecessary data source queries and cell redrawing, reducing performance. Check whether the state has actually changed before calling reloadData.
The third mistake — working with network requests without considering that the screen may be hidden again before the request completes. If you start a URLSession request in viewWillAppear and the user immediately navigates to another screen, the result may be applied to an already hidden View. Use cancellable tasks or check isViewLoaded and window before updating.
The fourth mistake — forgetting to call super. Not calling super.viewWillAppear can break parent controller behavior (UINavigationController, UITabBarController) and lead to incorrect gesture and transition handling. super should always be called.
The fifth mistake — modifying constraints without calling layoutIfNeeded. If you programmatically change constraints in viewWillAppear, UIKit does not apply them immediately — changes accumulate until the next layout pass. For immediate application of changes after constraint modification, call view.layoutIfNeeded(). This is especially important when adjusting the height of content-dependent elements.
The sixth mistake — attempting to perform animation in viewWillAppear. As mentioned above, UIKit is still processing the transition animation, and your animation may compete with the system one. If you need an element to appear with an effect, use incoming animation in viewDidAppear, and in viewWillAppear only configure the initial state: transparency 0, transform at 0.8 scale, and so on.
The seventh mistake — ignoring the animated parameter. Some developers do not check the animated value in viewWillAppear and perform operations that should depend on whether animation is present. For example, hiding NavigationBar when animated = false can be done without animation, and when animated = true — with animation, so the transition looks smooth. Always pass the animated parameter to the appropriate UIKit methods.
The eighth mistake — modifying UI when the screen is not visible. If you start a network request in viewWillAppear and its completion block updates the UI when the screen may have already disappeared, the user will see flickering or inconsistent state. Always check isViewLoaded and window before updating UI in closures. This simple action prevents crashes and unnecessary interface redraws.
Frequently Asked Questions
viewWillAppear is called before the appearance animation begins, when the View is not yet visible. viewDidAppear is called after the animation completes, when the screen is fully displayed and available for interaction.
Under normal conditions, viewWillAppear is always called when the screen appears. The exception is a force quit of the application, in which UIKit does not have time to call the Lifecycle methods.
Yes, absolutely. UIKit uses this call for internal coordination with UINavigationController and UITabBarController. Without super, gestures and transition animations may break.
On every tab switch. UIKit calls viewWillAppear on the selected tab's controller immediately after the user taps the corresponding icon in the TabBar.
Use controller properties or a shared data source. Before calling popViewController, set the required values on the previous controller, and they will already be available in its viewWillAppear.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also