UIKit: View Controllers & Lifecycle
What is a view controller?
In UIKit, a screen is managed by a UIViewController. It owns a tree of views (the visual elements) and contains the logic for that screen. Think of it as the “brain” of one screen: it sets up the UI, responds to user actions, and reacts as the screen appears and disappears.
A basic view controller
class ProfileViewController: UIViewController {
private let nameLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
nameLabel.text = "Anand Gaur"
nameLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(nameLabel)
NSLayoutConstraint.activate([
nameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
nameLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20)
])
}
}
The view controller lifecycle
UIKit calls a series of methods as your screen comes and goes. Knowing the order tells you exactly where to put each kind of code:
viewDidLoad()— called once, when the view is first loaded into memory. Do one-time setup here (add subviews, configure layout).viewWillAppear(_:)— just before the screen becomes visible. Refresh data that might have changed.viewDidAppear(_:)— after the screen is fully visible. Start animations or analytics.viewWillDisappear(_:)— the screen is about to leave. Save state, pause work.viewDidDisappear(_:)— the screen has gone.
Why viewDidLoad vs viewWillAppear matters
viewDidLoad runs only once, so building the UI there is efficient. But it does not run again when you return to the screen. If you need fresh data each time the screen appears (say, after editing a profile), put that refresh in viewWillAppear — otherwise you’ll show stale data.
Responding to actions
let button = UIButton(type: .system)
button.setTitle("Tap", for: .normal)
button.addTarget(self, action: #selector(didTap), for: .touchUpInside)
@objc func didTap() {
print("Button tapped")
}
Common mistakes
- Refreshing data in
viewDidLoadand wondering why it’s stale on return (useviewWillAppear). - Forgetting
translatesAutoresizingMaskIntoConstraints = falsewhen using Auto Layout in code. - Doing heavy work in
viewDidLoadthat delays the screen appearing.
Summary: A UIViewController manages one screen. Do one-time setup inviewDidLoad, and per-appearance refreshes inviewWillAppear. Learn the lifecycle order — it tells you where each piece of code belongs.