UIViewController viewDidLoad vs. viewWillAppear: What is the proper division of labor?
viewDidLoad is things you have to do once. viewWillAppear gets called every time the view appears. You should do things that you only have to do once in viewDidLoad - like setting your UILabel texts. However, you may want to modify a specific part of the view every time the user gets to view it, e.g. the iPod application scrolls the lyrics back to the top every time you go to the "Now Playing" view.
However, when you are loading things from a server, you also have to think about latency. If you pack all of your network communication into viewDidLoad or viewWillAppear, they will be executed before the user gets to see the view - possibly resulting a short freeze of your app. It may be good idea to first show the user an unpopulated view with an activity indicator of some sort. When you are done with your networking, which may take a second or two (or may even fail - who knows?), you can populate the view with your data. Good examples on how this could be done can be seen in various twitter clients. For example, when you view the author detail page in Twitterrific, the view only says "Loading..." until the network queries have completed.
What is the difference between -viewWillAppear: and -viewDidAppear:?
In general, this is what I do:
ViewDidLoad - Whenever I'm adding controls to a view that should appear together with the view, right away, I put it in the
ViewDidLoad
method. Basically, this method is called whenever the view was loaded into memory. So for example, if my view is a form with 3 labels, I would add the labels here; the view will never exist without these forms.ViewWillAppear: I use
ViewWillAppear
usually just to update the data on the form. So, for the example above, I would use this to actually load the data from my domain into the form. Creation ofUIViews
is fairly expensive, and you should avoid as much as possible doing that on theViewWillAppear
method because when this gets called, it means that the iPhone is already ready to show theUIView
to the user, and anything heavy you do here will impact performance in a very visible manner (like animations being delayed, etc).ViewDidAppear: Finally, I'm using
ViewDidAppear
to start off new threads to things that would take a long time to execute, like for example doing a web service call to get extra data for the form above. The good thing is that because the view already exists and is being displayed to the user, you can show a nice "Waiting" message to the user while you get the data.
Difference between viewDidLoad and viewDidAppear
viewDidLoad
is called exactly once, when the view controller is first loaded into memory. This is where you want to instantiate any instance variables and build any views that live for the entire lifecycle of this view controller. However, the view is usually not yet visible at this point.
viewDidAppear
is called when the view is actually visible, and can be called multiple times during the lifecycle of a View Controller (for instance, when a Modal View Controller is dismissed and the view becomes visible again). This is where you want to perform any layout actions or do any drawing in the UI - for example, presenting a modal view controller. However, anything you do here should be repeatable. It's best not to retain things here, or else you'll get memory leaks if you don't release them when the view disappears.
See: https://developer.apple.com/documentation/uikit/uiviewcontroller
About viewController's viewDidLoad and viewWillAppear methods
I would like to add to Caleb's answer: Don't confuse the view controller and the view! The name viewDidLoad
clearly indicates that the method is invoked after the view has been loaded. It is the view controller that does the loading.
Some pointers regarding the lifecycle of views and the order in which messages are sent:
- Not an official Apple document, but I find this diagram really useful because it includes pretty much all of
UIViewController
's lifecycle overrides. - In the section Resource Management in View Controllers from Apple's "View Controller Programming Guide" there is a flowchart that depicts how views are initially loaded. It explains
loadView
andviewDidLoad
, also in conjunction with storyboards. - The section Responding to Display-Related Notifications from Apple's "View Controller Programming Guide" explains how to respond to views appearing and disappearing (
viewWillAppear:
et al) - If you are planning on implementing a container view controller: The UIViewController class reference has a good overview of how messages need to be sent by your subclass.
I'm stopping here. You can find more stuff yourself by googling for "uiviewcontroller life cycle".
May I use viewWillAppear instead of viewDidLoad for most of my initialization and setup?
It depends on what you intend to do after the form start-to-finish of loading the view.
You don't want to do too much in viewWillAppear
(Called when the view is ready to be shown) as it could impact performance; typically you want to do things like refresh a table, or update the text on a label etc. The viewDidLoad
method is called once the view is loaded and it is common to add things like buttons, labels etc, anything that you want to appear on the view. If you have anything tasks that may take long to execute, it is better to do them in the viewDidAppear
as the view has already been loaded; it is good practice to perform these methods on a separate thread, or at least provide the user with some sort of activity indicator until the work is done.
When to put into viewWillAppear and when to put into viewDidLoad?
Simple rule I use is this. viewDidLoad
is when the view's resources are loaded. The view is not drawn onscreen yet. So calculations and code dealing with the geometry and visuals of the view should not be put here. They should be in the viewWillAppear
or viewDidAppear
method.
Also viewWillAppear can be called multiple times
- When a popover/modal view is displayed and remove
- When an alert view/actionsheet/uiactivityController's view is displayed and removed.
For these reason, viewWillAppear
should not contain codes that takes longer to finish. (at least the code running on the main thread). Neither should codes that only needs to be run once per view display.
There are more I am sure but these are simple to remember and I hope it helps.
Related Topics
Adding Core Data to Existing Iphone Project
Firebase Notification Records/Log API
Hide Separator Line on One Uitableviewcell
How to Change the Device Orientation Programmatically in iOS 6
Shouldautorotatetointerfaceorientation Not Being Called in iOS 6
How to Use Auto Layout to Move Other Views When a View Is Hidden
Iphone Smooth Sketch Drawing Algorithm
Auto Layout Constraints Issue on iOS7 in Uitableviewcell
Unique Values of Array in Swift
Swift Nsdateformatter Not Working
How to Launch the Google Maps iPhone Application from Within My Own Native Application
Cocoa Graphing/Plotting Framework on iOS
How to Detect iPhone Is on Silent Mode
How to Get the Status of Bluetooth (On/Off) in iPhone Programmatically