Working with Navigation
1. Using UINavigationController
| Property | Value | Description |
|---|---|---|
| viewControllers | [UIViewController] |
Array of view controllers in the navigation stack |
| navigationBar | UINavigationBar |
The navigation bar associated with the navigation controller |
| topViewController | UIViewController? |
The top view controller in the navigation stack |
Example: Pushing a View Controller
let newViewController = MyViewController()
navigationController?.pushViewController(newViewController, animated: true)
Example: Customizing Navigation Bar
navigationBar.backgroundColor = .systemBackground
navigationBar.tintColor = .systemBlue
2. Pushing and Popping View Controllers
| Method | Description | Notes |
|---|---|---|
| pushViewController(_:animated:) | Pushes a view controller onto the navigation stack | Animated by default |
| popViewController(animated:) | Pops the top view controller from the navigation stack | Animated by default |
| popToViewController(_:animated:) | Pops view controllers to a specific view controller | Removes all view controllers above the target |
| popToRootViewController(animated:) | Pops all view controllers to the root | Clears entire navigation stack except root |
Example: Pushing a View Controller
let newViewController = MyViewController()
navigationController?.pushViewController(newViewController, animated: true)
Note: Navigation stack is managed by
UINavigationController. Ensure view controllers are properly initialized before pushing.Warning: Avoid pushing the same view controller multiple times to prevent stack bloat.
3. Customizing Navigation Bar
| Property | Value | Description |
|---|---|---|
| navigationBar.prefersLargeTitles | true / false |
Enables or disables large titles in the navigation bar. |
| navigationBar.backgroundColor | UIColor |
Sets the background color of the navigation bar. |
| navigationBar.titleTextAttributes | [NSAttributedString.Key: Any] |
Customizes the appearance of title text. |
| navigationBar.barTintColor | UIColor |
Sets the background color of the navigation bar. |
| navigationBar.tintColor | UIColor |
Sets the color of navigation bar items (buttons, text). |
Example: Setting Navigation Bar Background Color
let navBar = UINavigationBar()
navBar.barTintColor = UIColor.systemBlue
Example: Customizing Title Text Attributes
let attributes: [NSAttributedString.Key: Any] = [
.foregroundColor: UIColor.white,
.font: UIFont.boldSystemFont(ofSize: 18)
]
navBar.titleTextAttributes = attributes
Note: Large titles require iOS 11 or later and must be enabled in the navigation controller's
prefersLargeTitles property.
4. Using Navigation Bar Items
| Item Type | Description | Usage |
|---|---|---|
| navigationBarItems | Defines items to display in the navigation bar | navigationBarItems(leading: ..., trailing: ...) |
| leading | Items placed on the left side of the navigation bar | navigationBarItems(leading: Button("Back") { ... }) |
| trailing | Items placed on the right side of the navigation bar | navigationBarItems(trailing: Button("Save") { ... }) |
Example: Adding Navigation Bar Items
struct ContentView: View {
var body: some View {
NavigationView {
Text("Main Content")
.navigationBarItems(
leading: Button("Back") {
// Handle back action
},
trailing: Button("Save") {
// Handle save action
}
)
}
}
}
Note:
navigationBarItems is available in iOS 13 and later.5. Implementing Custom Back Button
| Property | Description | Usage |
|---|---|---|
| navigationBar.backItem | Represents the back button item in the navigation bar. | Used to customize the back button's title or image. |
| navigationBar.backIndicatorImage | Custom image for the back indicator (arrow) in the navigation bar. | Set to a custom image to replace default back arrow. |
| navigationBar.backIndicatorTransitionMaskImage | Mask image used for the back indicator transition animation. | Used to customize the animation of the back button. |
Example: Custom Back Button Title
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Customize the back button title
self.navigationItem.backBarButtonItem = UIBarButtonItem(
title: "Back",
style: .plain,
target: nil,
action: nil
)
}
}
Example: Custom Back Button Image
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Set custom back indicator image
let backImage = UIImage(named: "custom_back_arrow")
self.navigationController?.navigationBar.backIndicatorImage = backImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage
}
}
6. Using Large Titles
| Property | Value | Description |
|---|---|---|
| navigationController.navigationBar.prefersLargeTitles | true |
Enables large titles in the navigation bar |
| navigationController.navigationBar.largeTitleDisplayMode | automatic, always, never |
Controls when large titles are displayed |
Example: Enabling Large Titles
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .automatic
}
Note: Large titles are only supported in iOS 11 and later.
Key Points
- Large titles provide a more spacious and visually appealing navigation bar
- Requires setting
prefersLargeTitlestotrue - Use
largeTitleDisplayModeto control visibility
7. Hiding Navigation Bar
| Property | Value | Description |
|---|---|---|
| isNavigationBarHidden | false |
Boolean flag to control visibility of the navigation bar |
Example: Hide Navigation Bar
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
}
}
Example: Show Navigation Bar
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = false
}
}
Note: Setting
isNavigationBarHidden to true will hide the navigation bar, but it does not affect the status bar visibility.8. Implementing Navigation Delegates
| Delegate Method | Description | Return Value | Notes |
|---|---|---|---|
| navigationController(_:willShow:animated:) | Called before a view controller is displayed | void |
Use to perform last-minute adjustments before presentation |
| navigationController(_:didShow:animated:) | Called after a view controller is displayed | void |
Use to trigger actions after view controller is fully visible |
| navigationController(_:willPopViewController:animated:) | Called before popping a view controller from the stack | Bool |
Return false to prevent popping |
| navigationController(_:didPopViewController:animated:) | Called after popping a view controller from the stack | void |
Use to clean up or update state after pop |
Example: Implementing Navigation Delegate
class MyNavigationController: UINavigationController, UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
print("Will show view controller: \(viewController.title ?? "")")
}
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
print("Did show view controller: \(viewController.title ?? "")")
}
}
Note: Set the
delegate property of your navigation controller to an instance of your custom delegate class.
9. Using Segues in Storyboards
| Segue Type | Description | Usage |
|---|---|---|
| Show | Pushes a new view controller onto the navigation stack | Used for hierarchical navigation |
| Present Modally | Presents a view controller as a modal sheet | For temporary or contextual interactions |
| Show Detail | Replaces the detail view in a split view controller | Used in iPad multitasking layouts |
Example: Creating a Show Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowDetail" {
let detailVC = segue.destination as! DetailViewController
detailVC.item = selectedItem
}
}
Note: Set the segue identifier in Interface Builder to match the
prepare(for:sender:) check.Warning: Avoid using
performSegue(withIdentifier:sender:) without checking if the segue exists to prevent runtime crashes.10. Passing Data Between View Controllers
| Method | Description | Code Example |
|---|---|---|
| Segue | Pass data using prepare(for:sender:) method | |
| Direct Assignment | Assign properties directly to the destination view controller | |
| Closure | Use closure to pass data back from child view controller | |
Example: Using Segue to Pass Data
class MasterViewController: UIViewController {
var dataArray = ["Item 1", "Item 2", "Item 3"]
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let detailVC = segue.destination as? DetailViewController,
let indexPath = tableView.indexPathForSelectedRow {
detailVC.selectedItem = dataArray[indexPath.row]
}
}
}