Working with View Controllers
1. Creating View Controllers
| Method | Description | Code Example |
|---|---|---|
| init() | Initializes a new view controller with default settings | let viewController = UIViewController() |
| init(nibName:bundle:) | Initializes a view controller with a specific nib file and bundle | let viewController = UIViewController(nibName: "CustomView", bundle: nil) |
| init(coder:) | Initializes a view controller from an archive (used with Storyboards) | |
Note: When using Storyboards, the
init?(coder:) initializer is called automatically.2. Understanding View Lifecycle Methods
| Method | Description | Notes |
|---|---|---|
| viewDidLoad() | Called after the view controller's view is loaded into memory. | Perfect for initial setup, such as configuring UI elements or setting up data sources. |
| viewWillAppear(_:) | Called just before the view is added to the view hierarchy. | Useful for preparing the view for display, such as animating in or updating content. |
| viewDidAppear(_:) | Called after the view has been added to the view hierarchy and is visible. | Good for starting animations or beginning tasks that require a visible view. |
| viewWillDisappear(_:) | Called just before the view is removed from the view hierarchy. | Useful for pausing animations or saving state before the view disappears. |
| viewDidDisappear(_:) | Called after the view has been removed from the view hierarchy. | Useful for cleaning up resources or stopping tasks that were started in viewWillAppear. |
| viewWillLayoutSubviews() | Called just before the view's layout subviews are updated. | Useful for making adjustments to subviews before they are laid out. |
| viewDidLayoutSubviews() | Called after the view's layout subviews are updated. | Useful for making adjustments to subviews after they have been laid out, such as adjusting frames or constraints. |
Example: Using viewDidLoad to set up a view controller
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "My View Controller"
view.backgroundColor = .systemBackground
}
}
3. Using viewDidLoad for Setup
viewDidLoad is called after the view controller's view has been loaded into memory. It's the ideal place to perform initial setup tasks that need the view to exist.
| Method | Description | When It's Called |
|---|---|---|
| viewDidLoad() | Called once when the view is first loaded | After loadView and before the view appears |
Example: Setting up UI in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Set up the view hierarchy
view.backgroundColor = .systemBackground
// Configure UI elements
let label = UILabel()
label.text = "Hello, World!"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
Note: Avoid heavy computation or network calls in
viewDidLoad. Use viewWillAppear or viewDidAppear for such operations.4. Using viewWillAppear and viewDidAppear
| Method | Description | Usage |
|---|---|---|
| viewWillAppear(_: | UIViewController method called before the view is added to the view hierarchy. |
Use for preparing the view before it appears (e.g., updating UI elements, starting animations). |
| viewDidAppear(_: | UIViewController method called after the view has been added to the view hierarchy. |
Use for actions that should happen after the view is fully visible (e.g., starting timers, logging analytics). |
Example: Using viewWillAppear and viewDidAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("View will appear")
// Update UI or prepare for appearance
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("View did appear")
// Start timers or analytics
}
Note: Both methods are called every time the view appears, even if it's already in the view hierarchy.
5. Using viewWillDisappear and viewDidDisappear
| Method | Description | Usage |
|---|---|---|
| viewWillDisappear(_ animated: Bool) | Called when the view controller's view is about to be removed from the view hierarchy | Use for cleaning up resources or stopping animations before the view disappears |
| viewDidDisappear(_ animated: Bool) | Called after the view controller's view has been removed from the view hierarchy | Use for final cleanup or logging after the view is no longer visible |
Example: Managing view lifecycle
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Stop animations or timers
timer?.invalidate()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Perform cleanup
print("View disappeared")
}
Note: Both methods are called when the view is removed from the hierarchy, but
viewWillDisappear is called before the view is actually removed.6. Managing View Hierarchy
| Method | Description | Notes |
|---|---|---|
| addChild(_:) | Adds a child view controller to the current view controller | Must be called before adding the child's view to the hierarchy |
| removeFromParent() | Removes the view controller from its parent | Must be called before removing the child's view |
| view.addSubview(_:) | Adds a subview to the view controller's main view | Used for direct view manipulation |
| viewWillDisappear(_:) | Called when the view is about to be removed from the hierarchy | Use for cleanup or state preservation |
Example: Adding a Child View Controller
class ParentViewController: UIViewController {
let childVC = ChildViewController()
override func viewDidLoad() {
super.viewDidLoad()
addChild(childVC)
view.addSubview(childVC.view)
childVC.didMove(toParent: self)
}
}
Example: Removing a Child View Controller
class ParentViewController: UIViewController {
let childVC = ChildViewController()
func removeChild() {
childVC.willMove(toParent: nil)
childVC.view.removeFromSuperview()
childVC.removeFromParent()
}
}
Note: Always call
didMove(toParent:) after adding a child view controller, and willMove(toParent: nil) before removing it.
7. Working with Navigation Controllers
| Property | Description | Notes |
|---|---|---|
| navigationController | Reference to the navigation controller managing this view controller | Read-only property |
| navigationBar | Access to the navigation bar associated with this controller | Can be customized for appearance and behavior |
Example: Pushing a View Controller onto Navigation Stack
let newViewController = MyViewController()
navigationController?.pushViewController(newViewController, animated: true)
Example: Customizing Navigation Bar Appearance
UINavigationBar.appearance().backgroundColor = UIColor.blue
Note: Navigation controllers manage a stack of view controllers, allowing users to navigate back using the "back" button.
Navigation Controller Workflow
- Initialize a
UINavigationControllerwith a root view controller - Push new view controllers onto the stack using
pushViewController(_:animated:) - Pop view controllers using
popViewController(animated:)orpopToViewController(_:animated:)
8. Using Tab Bar Controllers
A UITabBarController is used to manage a set of view controllers, each associated with a tab in a tab bar. It provides a way to switch between different views or modes within an app.
| Property | Type | Description |
|---|---|---|
| viewControllers | [UIViewController] |
Array of view controllers to be displayed in the tab bar. |
| selectedIndex | Int |
The index of the currently selected view controller. |
| tabBar | UITabBar |
The tab bar managed by the controller. |
Example: Setting up a Tab Bar Controller
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "Home"
view.backgroundColor = .systemBlue
}
}
class ViewControllerB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "Profile"
view.backgroundColor = .systemGreen
}
}
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let vc1 = ViewControllerA()
let vc2 = ViewControllerB()
viewControllers = [vc1, vc2]
}
}
Note: The
UITabBarController manages the lifecycle of its view controllers, including their presentation and dismissal.
Key Features of Tab Bar Controllers
- Each view controller is associated with a tab in the tab bar.
- Supports customization of tab bar appearance and behavior.
- Automatically handles switching between view controllers when a tab is selected.
9. Implementing Modal Presentations
| Property | Value | Description |
|---|---|---|
| modalPresentationStyle | .fullScreen, .pageSheet, .formSheet, .currentContext, .overFullScreen |
Defines how the view controller is presented modally |
| modalTransitionStyle | .coverVertical, .flipHorizontal, .crossDissolve, .partialCurl |
Defines the transition animation when presenting modally |
Example: Presenting a Modal View Controller
let modalViewController = MyModalViewController()
modalViewController.modalPresentationStyle = .formSheet
modalViewController.modalTransitionStyle = .coverVertical
present(modalViewController, animated: true)
Note: Use
.formSheet for iPad and .fullScreen for iPhone to ensure proper presentation.
Example: Dismissing a Modal View Controller
@IBAction func dismissButtonTapped(_ sender: UIButton) {
dismiss(animated: true)
}
10. Using Container View Controllers
A container view controller manages the layout and behavior of one or more child view controllers. It provides a structured way to organize and present multiple views within a single interface.
| Property | Description | Usage |
|---|---|---|
| childViewControllers | Array of child view controllers managed by the container. | let children = self.childViewControllers |
| viewControllers | Read-only array of view controllers in the container. | let viewControllers = self.viewControllers |
| presentedViewController | View controller currently presented modally. | let modalVC = self.presentedViewController |
Example: Adding a Child View Controller
class ParentViewController: UIViewController {
let childVC = ChildViewController()
override func viewDidLoad() {
super.viewDidLoad()
addChild(childVC)
childVC.view.frame = view.bounds
view.addSubview(childVC.view)
childVC.didMove(toParent: self)
}
}
Example: Removing a Child View Controller
class ParentViewController: UIViewController {
let childVC = ChildViewController()
func removeChild() {
childVC.willMove(toParent: nil)
childVC.view.removeFromSuperview()
removeFromParent()
}
}
Note: When adding or removing child view controllers, always call
didMove(toParent:) or willMove(toParent:) respectively to notify the system of the change.
Container View Controller Types
- UINavigationController: Manages a stack of view controllers.
- UITabBarController: Displays one view controller at a time from a set of view controllers.
- UISplitViewController: Displays two view controllers side-by-side on larger devices.
- UIPageViewController: Allows navigation between pages of content using swipe gestures.
11. Understanding View Controller Transitions
| Transition Type | Description | Usage | Notes |
|---|---|---|---|
| Present | Presents a view controller modally | present(viewController, animated: true) |
Standard for showing new screens |
| Push | Pushes a view controller onto a navigation stack | navigationController?.pushViewController(viewController, animated: true) |
Used in navigation controllers |
| Pop | Pops the current view controller off the navigation stack | navigationController?.popViewController(animated: true) |
Reverses a push transition |
| Replace | Replaces the current view controller in the navigation stack | navigationController?.setViewControllers([newVC], animated: true) |
Useful for replacing entire stacks |
Example: Presenting a Modal View Controller
let modalVC = MyModalViewController()
modalVC.modalPresentationStyle = .fullScreen
self.present(modalVC, animated: true)
Example: Pushing a View Controller
let detailVC = DetailViewController()
navigationController?.pushViewController(detailVC, animated: true)
Note: Transitions can be customized using
UIViewControllerAnimatedTransitioning or UIViewControllerContextTransitioning.