Keep away from people who try to belittle your ambitions. Small people always do that, but the really great make you feel that you, too, can become great. -Mark Twain
In this lesson, we'll discuss and walk through how our application creates views.
- Connect the View Controller to a
.swift
file - Create the connection between the View Controller in the
Main.storyboard
file with theViewController.swift
file - Explain that the
View
object they can be selected or modified within the View Controller Scene is directly tied with theviewDidLoad()
method - Explain when the
viewWillAppear(_:)
,viewDidAppear(_:)
,viewDillDisappear(_:)
andviewDidDisappear(_:)
methods are called - Change the
backgroundColor
of theview
So far, you've learned how to create graphical user interfaces for your iOS apps in Xcode. You've probably noticed, though, that your graphical interfaces don't actually do anything. You haven't written any Swift code to make your interface work. It's just some labels and buttons!
You've probably noticed, however, that in every interface, the first thing you've dragged into the canvas is a view controller. Far from just being a blank white rectangle on the Interface Builder canvas, that view controller is actually a key piece of the puzzle: It contains the code that makes a view do something.
Fork and clone this lesson. This isn't a lab and you won't need to make a pull request, but you'll be coding along so follow along with the steps.
Take a look at your file listing. You should see a file called ViewController.swift
. This is created as part of every new iOS project. It is the code portion of that main view controller you've been creating in every app. By default, it doesn't do anything useful, but that's about to change.
But before we get started writing code, let's talk about how your application creates views.
When a user launches your application, the first thing the application needs to do is display the initial view of the application. It looks at the main storyboard file to find the initial view controller. It then creates that view controller, and calls a few methods on it to initialize it. The view controller, in turn, will often do a bit of initialization to its view and any subviews. Finally, after all that loading, the view is drawn to the screen and displayed to the user. This process is known as the view life cycle.
Whoo! That was a lot to digest at once, so let's take it piece by piece.
First, take a look at the Main.storyboard
file. It has a pretty simple interface consisting of four movie poster thumbnails and a piece of film trivia.
How does that view get associated with a view controller?
It may seem like magic, but it's actually pretty straightforward. Select the View Controller in the object listing.
Bring up the view controller's Identity Inspector.
The first section of the Identity Inspector is called *Custom Class. This is where you associate a view controller with its corresponding code.
By default, the Custom Class is already set to ViewController. This means that the selected view controller is associated with the code in the ViewController.swift
file, which means that the code you write in that file will determine how the view controller behaves and responds to input, and draws things to the screen.
Click the grey arrow next to ViewController in the Custom Class dropdown menu to open ViewController.swift
.
See? The fact that clicking on the grey arrow opened ViewController.swift
demonstrates that these two items—the view controller in Main.storyboard
and the ViewController.swift
file—are tied together. They are associated with each other.
Right now, ViewController.swift
is pretty barren:
// ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
There is one class, ViewController
, which represents the view controller in the Main.storyboard
file. That class contains one method, viewDidLoad()
, which doesn't do much right now.
Remember when we talked about how your application is loaded when the user launches it? viewDidLoad()
is one of the initialization methods that is called on the initial view controller. viewDidLoad()
is called before anything is shown to the user. It gives your app a chance to set some initial configuration in the view, and do some other minor tasks before the view is shown to the user for the first time. When viewDidLoad()
is called, the view has been created in memory, but it has not yet been displayed.
To see this in action, add a print()
call to the existing viewDidLoad()
method, after the call to super()
. Have it print something like "viewDidLoad() called":
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad() called")
}
Now, build and run your app in the simulator. You'll see the debugger output pane pop open at the bottom of Xcode's editor. Notice that right before the view appears, you'll see the message "viewDidLoad() called" logged to the console.
When launching an app and initializing the views, viewDidLoad()
is the first of several methods called. Once the view has actually been loaded (into memory, from the .storyboad
file), the Cocoa Touch framework will then call viewWillAppear(_:)
. This method is called when the view is about to appear (be shown on the screen), but before it is actually displayed. This method allows you to do some further customization.
By default, your view controller will not override this method. You can add it yourself, though, and it will get called. Add a viewWillAppear(_:)
method that prints "viewWillAppear(_:) called" to the console. Your complete ViewController
implementation should look like this when you're done:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad() called")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear(_:) called")
}
}
Build and run your application again. Take note of when these two messages (the one for viewDidLoad()
, and the one for viewWillAppear(_:)
) are called.
Take note of the order in which these methods were called. viewDidLoad()
was called first, followed by viewWillAppear(_:)
.
If both these methods are called, what's the difference between the two? viewDidLoad()
is only called once, when the view is loaded from a .storyboard
file. viewWillAppear(_:)
is called every time the view appears. In this simple apps, that means it is only called once. However, imagine your app has several views, and you can move between them. viewWillAppear(_:)
is called every time your view is displayed. viewDidLoad()
is used for initialization that only has to occur once, wherehas viewWillAppear(_:)
is used for initialization that occurs every time your view is displayed. As you start to write more complicated iOS apps, the differences between the two methods will become much more apparent.
There is one final method called when your view is being displayed to the user: viewDidAppear(_:)
. This method is called after the view is shown to the user. If you change something inside this method (such as animating an image or a piece of text), the user will see it change.
Like viewWillAppear(_:)
, viewDidAppear(_:)
is not defined in your view controller by default, but you can add it. Add a definition of viewDidAppear(_:)
that prints a message to the console. Your complete implementation of ViewController
should now look like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad() called")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear(_:) called")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear(_:) called")
}
}
Build and run your application again. Like before, pay careful attention to the messages in the debugging console. What order do you expect them to appear in? You should see output like this:
Now that you have an understanding of the view life cycle, let's demonstrate it in a more practical manner: By changing the color of the view's background color. You can already do that manually in the view's Attributes Inspector, but wouldn't it be more fun to set the background to a random color every time you launch the app? Of course it would be!
You can change the background color to a random color with a simple line of code:
view.backgroundColor = UIColor.randomColor()
Which method should you put this line of code in, though?
If you put it in viewDidAppear(_:)
, the user will first see the white background color, and then the random color will "pop" in. Go ahead and try it! You probably want the user to see the random color right from the get-go, though, so viewDidAppear(_:)
is probably not the right option.
What happens if you put it in viewWillAppear(_:)
? Try it out. You won't see the random color "pop" in anymore. Mission accomplished, right? The only problem with putting the code in viewWillAppear(_:)
is that the background color will change every time the view appears. In this simple app, that only occurs once, but in a more complicated app with multiple screens, it would mean the user would see a new color every time they navigated back to this screen.
That may be what you want, but you can also consider putting the code that sets the background color in viewDidLoad()
. This will change the background color once, when the view is loaded. Try putting the code there. Your complete implementation of ViewController
will look like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad() called")
view.backgroundColor = UIColor.randomColor()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear(_:) called")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear(_:) called")
}
}
Try building and running your application several times to see what colors you get!
One thing to note before ending the lesson: The line of code that changed the background color referenced a variable called view
.
view.backgroundColor = UIColor.randomColor()
view
is an instance variable that is a part of every view controller. You'll learn more about this in later lessons, but it's important to note that the variable view
is not random or magical; it's just an instance variable.
View View LifeCycle on Learn.co and start learning to code for free.