What is UIViewController?
UIViewController
is the base class for managing views in an iOS application. It provides lifecycle methods, navigation, and user interaction handling. Every screen in an iOS app is typically represented by a UIViewController
.
1. Key Features of UIViewController
✅ Manages the View Hierarchy – Handles UI elements on the screen.
✅ Manages the View Lifecycle – Responds to events like loading, appearing, and disappearing.
✅ Handles User Interaction – Processes button taps, gestures, and inputs.
✅ Supports Navigation – Push, pop, and present other view controllers.
✅ Manages Memory Efficiently – Releases resources when not in use.
2. UIViewController Lifecycle
A UIViewController
goes through several states during its lifecycle:
Lifecycle Methods & Usage
Method | Purpose |
---|---|
viewDidLoad() | Called when the view is loaded into memory. Used for setup. |
viewWillAppear() | Called before the view appears on the screen. |
viewDidAppear() | Called after the view appears. Used for animations. |
viewWillDisappear() | Called before the view disappears. |
viewDidDisappear() | Called after the view disappears. |
viewWillLayoutSubviews() | Called before layout changes. |
viewDidLayoutSubviews() | Called after layout changes. |
Example: Lifecycle Methods in Action
import UIKit
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("View loaded into memory")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("View will appear on screen")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("View appeared on screen")
}
}
3. Creating a UIViewController
3.1 Using Storyboard
- Open
Main.storyboard
. - Drag a
UIViewController
from the Object Library. - Set the
Storyboard ID
in the Identity Inspector. - Create a new Swift file and subclass
UIViewController
. - Connect the Storyboard
UIViewController
to this class.
3.2 Creating Programmatically
import UIKit
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
}
}
// Presenting the view controller in AppDelegate or SceneDelegate
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = MyViewController()
window.makeKeyAndVisible()
✅ This programmatically creates a ViewController with a white background.
4. Navigating Between ViewControllers
4.1 Using Navigation Controller
A UINavigationController
is used to push and pop view controllers.
let secondVC = SecondViewController()
navigationController?.pushViewController(secondVC, animated: true)
✅ This pushes SecondViewController
onto the navigation stack.
4.2 Presenting Modally
let modalVC = ModalViewController()
modalVC.modalPresentationStyle = .fullScreen
present(modalVC, animated: true, completion: nil)
✅ This presents ModalViewController
in fullscreen.
4.3 Dismissing a ViewController
dismiss(animated: true, completion: nil)
✅ This dismisses the current ViewController.
5. Passing Data Between ViewControllers
5.1 Using Properties
class SecondViewController: UIViewController {
var receivedText: String = ""
override func viewDidLoad() {
super.viewDidLoad()
print("Received data: \(receivedText)")
}
}
// Passing data
let secondVC = SecondViewController()
secondVC.receivedText = "Hello from FirstVC!"
navigationController?.pushViewController(secondVC, animated: true)
5.2 Using Delegates (Recommended for Passing Data Back)
- Define a Protocol in SecondViewController
protocol SecondViewControllerDelegate: AnyObject {
func didSendData(_ data: String)
}
class SecondViewController: UIViewController {
weak var delegate: SecondViewControllerDelegate?
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
delegate?.didSendData("Data from SecondVC")
}
}
- Conform to the Protocol in FirstViewController
class FirstViewController: UIViewController, SecondViewControllerDelegate {
func didSendData(_ data: String) {
print("Received: \(data)")
}
func navigateToSecondVC() {
let secondVC = SecondViewController()
secondVC.delegate = self
navigationController?.pushViewController(secondVC, animated: true)
}
}
✅ This enables data passing back from SecondViewController
to FirstViewController
.
6. Adding UI Elements to UIViewController
6.1 Adding a Button Programmatically
let myButton = UIButton(type: .system)
myButton.setTitle("Click Me", for: .normal)
myButton.frame = CGRect(x: 100, y: 200, width: 150, height: 50)
myButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
view.addSubview(myButton)
@objc func buttonTapped() {
print("Button Clicked!")
}
6.2 Adding a Label
let myLabel = UILabel()
myLabel.text = "Hello, World!"
myLabel.frame = CGRect(x: 50, y: 100, width: 200, height: 40)
view.addSubview(myLabel)
✅ These examples show how to dynamically add UI elements to a ViewController.
7. Managing Memory Efficiently
To avoid memory leaks, use weak references and remove observers when necessary.
7.1 Removing Observers
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
7.2 Handling Retain Cycles
Use [weak self]
in closures to prevent memory leaks:
myButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
8. Handling Rotation and Size Changes
8.1 Detecting Orientation Changes
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
print("Device rotated, new size: \(size)")
}
8.2 Supporting Different Orientations
Add this to Info.plist
:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
✅ This allows the app to support multiple screen orientations.
9. Summary
✔️ UIViewController
manages screens in an iOS app.
✔️ Provides lifecycle methods to handle view loading and memory management.
✔️ Supports navigation and data passing between screens.
✔️ Can be customized programmatically or via Storyboard.
✔️ Uses delegates and closures for efficient communication between view controllers.
Would you like a specific ViewController feature implementation in your project? 🚀