UINavigationBar
iOS Development
Programming
iOS UI
Swift

UINavigationBar - Set title programmatically?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Setting a navigation title programmatically in iOS is straightforward, but teams often hit issues when using large titles, custom title views, UINavigationController hierarchies, or SwiftUI bridges. The correct API depends on where you want the title state to live.

In UIKit, the title belongs to UINavigationItem of the current view controller. In practice, you usually set self.title or navigationItem.title inside viewDidLoad/viewWillAppear.

Core Sections

1. Basic title setting in UIKit

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        title = "Profile"
7        // equivalent: navigationItem.title = "Profile"
8    }
9}

This works when the controller is embedded in a UINavigationController.

If title depends on dynamic data loaded later:

swift
func updateTitle(username: String) {
    navigationItem.title = username
}

2. Large titles and appearance configuration

Large titles require both nav controller preference and item display mode.

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    title = "Dashboard"
4    navigationController?.navigationBar.prefersLargeTitles = true
5    navigationItem.largeTitleDisplayMode = .always
6}

Global appearance example:

swift
1let appearance = UINavigationBarAppearance()
2appearance.configureWithOpaqueBackground()
3appearance.backgroundColor = .systemBackground
4appearance.titleTextAttributes = [.foregroundColor: UIColor.label]
5appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.label]
6
7UINavigationBar.appearance().standardAppearance = appearance
8UINavigationBar.appearance().scrollEdgeAppearance = appearance

3. Custom title views

For logos or composite title layouts, use navigationItem.titleView.

swift
1let label = UILabel()
2label.text = "Orders"
3label.font = .boldSystemFont(ofSize: 17)
4label.textColor = .label
5label.sizeToFit()
6
7navigationItem.titleView = label

You can set an image view similarly. Keep title view compact and accessible.

4. Timing and lifecycle considerations

If title changes based on state that can update while returning to screen, set in viewWillAppear.

swift
1override func viewWillAppear(_ animated: Bool) {
2    super.viewWillAppear(animated)
3    navigationItem.title = viewModel.currentTitle
4}

In tab-based apps with nested navigation controllers, ensure you are updating the visible controller’s navigationItem, not a parent container.

Common Pitfalls

  • Setting title on a controller that is not embedded in a UINavigationController.
  • Updating navigationController?.title instead of current view controller’s navigationItem.title.
  • Expecting large titles without enabling prefersLargeTitles and display mode.
  • Overusing custom titleView with complex layout that breaks in compact widths.
  • Changing title in background callbacks without dispatching UI updates to main thread.

Summary

Programmatic navigation titles in UIKit should be set on the current controller’s navigationItem (or title). Add large-title or custom-view configuration as needed, and choose lifecycle timing based on whether title is static or dynamic. Keeping title ownership clear prevents most navigation bar inconsistencies.

In apps with localization, avoid hardcoded titles in controllers wherever possible. Bind title strings through localization helpers or view models so language changes and A/B text updates remain centralized. This also helps testing because title logic can be validated independently from view lifecycle quirks. If title depends on asynchronous data (for example fetched entity name), update it on the main thread and provide a sensible placeholder title to avoid blank navigation bars during loading.

When mixing UIKit and SwiftUI, title ownership can become confusing. If a SwiftUI view is hosted inside a navigation controller, make sure only one layer is responsible for setting title at a time. Conflicting updates from both frameworks can cause flicker or unexpected overrides. Establishing a clear convention per screen keeps navigation behavior predictable.

In complex apps, adding navigation-title assertions to UI tests can prevent regressions where titles disappear after refactors in coordinator or routing layers. This is especially useful for flows that reuse controllers and update title dynamically as state changes.

Another practical tip is to keep title update logic in one method per controller instead of scattering assignments across callbacks. Centralized updates make future changes to localization, analytics, and accessibility labels easier to maintain.

Consistency in title ownership greatly reduces navigation bugs.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.