iOS development
UIViewController
viewWillAppear
viewDidAppear
app lifecycle

What is the difference 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

viewWillAppear: and viewDidAppear: are close together in the UIViewController lifecycle, but they are meant for different kinds of work. The first runs just before the view becomes visible, while the second runs after the transition has completed and the view is already on screen.

Timing Difference

viewWillAppear: is called when the controller is about to show its view. This is your last reliable moment to update visible state before the user sees the screen.

objectivec
1- (void)viewWillAppear:(BOOL)animated {
2    [super viewWillAppear:animated];
3    self.titleLabel.text = self.viewModel.screenTitle;
4    [self.tableView reloadData];
5}

viewDidAppear: runs after the view is fully presented:

objectivec
1- (void)viewDidAppear:(BOOL)animated {
2    [super viewDidAppear:animated];
3    [self.searchField becomeFirstResponder];
4}

That distinction matters because some actions only make sense after the screen is actually visible.

What Belongs in viewWillAppear:

Use viewWillAppear: for work that should be reflected immediately when the screen becomes visible:

  • refreshing labels, badges, or table content
  • applying theme or state changes
  • hiding or showing navigation controls
  • syncing UI with data that may have changed while the screen was off-screen

For example, if the previous controller edits a profile and then navigates back, viewWillAppear: is a good place to update the displayed name and avatar so the user sees the fresh values right away.

objectivec
1- (void)viewWillAppear:(BOOL)animated {
2    [super viewWillAppear:animated];
3
4    self.nameLabel.text = self.user.displayName;
5    self.emailLabel.text = self.user.emailAddress;
6    [self.navigationController setNavigationBarHidden:NO animated:animated];
7}

What Belongs in viewDidAppear:

Use viewDidAppear: for actions that require the view to be on screen or that should start only after the presentation transition finishes:

  • starting animations
  • kicking off analytics screen tracking
  • presenting alerts
  • focusing a text field
  • starting camera or location work tied to visible UI
objectivec
1- (void)viewDidAppear:(BOOL)animated {
2    [super viewDidAppear:animated];
3
4    [self.spinner stopAnimating];
5    [self.searchField becomeFirstResponder];
6    [Analytics trackScreen:@"Search"];
7}

Trying to do these in viewWillAppear: can lead to awkward timing, especially during animated navigation transitions.

Why It Matters for User Experience

Heavy work in viewWillAppear: can delay the screen from appearing smoothly because it runs before the transition is finished. On the other hand, deferring everything to viewDidAppear: can cause visible flicker because the user sees stale UI before your updates land.

A good rule is:

  • if the user should see the result immediately, prefer viewWillAppear:
  • if the work depends on visible presentation, prefer viewDidAppear:

Interaction with viewDidLoad

Developers often mix these methods with viewDidLoad, but they solve a different problem. viewDidLoad is for one-time setup after the view is loaded into memory, not for repeated appearance work.

objectivec
1- (void)viewDidLoad {
2    [super viewDidLoad];
3    self.tableView.dataSource = self;
4    self.tableView.delegate = self;
5}

If code needs to run every time the screen reappears, putting it in viewDidLoad is wrong because that method may run only once for the lifetime of the controller instance.

Common Pitfalls

  • Doing expensive synchronous work in viewWillAppear: and making the transition feel slow.
  • Presenting alerts or modal UI in viewWillAppear: when the screen is still transitioning.
  • Putting repeated appearance logic in viewDidLoad even though that method may run only once.
  • Starting observers, timers, or analytics in viewDidAppear: without matching cleanup later.
  • Deferring visible UI refreshes until viewDidAppear: and causing flicker with stale on-screen content.

Summary

  • 'viewWillAppear: runs just before the view becomes visible.'
  • 'viewDidAppear: runs after the view is fully on screen.'
  • Put pre-display UI refresh work in viewWillAppear:.
  • Put post-display actions such as animations, focus, and alerts in viewDidAppear:.
  • Keep one-time setup in viewDidLoad, not in appearance callbacks.

Course illustration
Course illustration

All Rights Reserved.