Swift – View Controller Lifecycle
As you develop iOS apps you will use more and more features of the UIViewController. You will want code to run before the view shows to the user, after it shows and after it disappears. It’s important to understand the UIViewController lifecycle, and the following stages of it:
- viewDidLoad()
- viewWillAppear(_ animated: Bool)
- viewDidAppear(_ animated: Bool)
- viewWillDisappear(_ animated: Bool)
- viewDidDisappear(_ animated: Bool)
viewDidLoad()
This is the first method to be called when your view controller loads. It’s a good place to do any initialization you may not have done in the storyboard such as setting constraints, and any one-time work. If you go to another screen and come back this function will not run again, unless your app is running low on memory and it has discarded the view previously loaded, which is very rare.
viewWillAppear(_ animated: Bool)
This is called right before your view actually displays to the user. It’s a good time to do any setup for the view that needs to be run everytime you show this view.
Note that this is called everytime the view is about to be shown on screen, and the code is run before the user is shown the view.
viewDidAppear(_ animated: Bool)
This is called when the screen is shown to the user. This is a good place to put code where you might need to get the position of elements on the screen and run animations.
viewWillDisappear(_ animated: Bool)
This is called right before the view will disappear. This is when the user moves to another screen, e.g a button to show the app settings screen. This can be a good place to hide the keyboard, save state information and cancel anything that might be running.
viewDidDisappear(_ animated: Bool)
This is called once the view has been removed from the screen.
Now you know what each of these functions do, the diagram below outlines this lifecycle – it might be easier to visualize how this works:
View Controller Lifecycle in code – example
Now we see how it works, lets implement these functions in a demo app, with some print statements so you can see it how the view controller lifecycle works in code, I have created a simple app with two screens as follows:
The main screen (With the next screen button) code is as follows:
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. print("viewDidLoad") } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) print("viewWillAppear") } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) print("viewDidAppear") } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) print("viewWillDisappear") } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) print("viewDidDisappear") }
Note, we call super.functionName for each function in the view controller lifecycle. E.g super.viewWillAppear(animated) – this is good practice to call the super class function, as we are overriding it we want to ensure any code is called from the parent class. Unless you have a specified reason not to I would recommend doing this.
When we first run our app we see the following output in the console:
viewDidLoad viewWillAppear viewDidAppear
When we tap the button to go to the next screen, we then see the following output:
viewWillDisappear viewDidDisappear
Then when we go back to the first screen, we see the following output:
viewWillAppear viewDidAppear
As we can see viewDidLoad is only called once when the view first loads up. When we go to the next screen the viewWillDisappear and viewDidDisappear functions are called. Then we go back to the first screen and only the viewWillAppear and viewDidAppear functions are called the second time around.