Swift
iOS Development
Navigation Bar
UI Customization
App Design

how to change navigationitem title color

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Changing the navigation title color in iOS depends on the navigation bar appearance APIs and the iOS version you target. Old global style APIs still work in some cases, but modern apps should use UINavigationBarAppearance for consistent behavior. Applying the correct appearance at the right lifecycle point prevents flicker and mixed styles.

Modern Approach with UINavigationBarAppearance

For iOS 13 and newer, configure title attributes through appearance objects.

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        view.backgroundColor = .systemBackground
7        title = "Profile"
8
9        let appearance = UINavigationBarAppearance()
10        appearance.configureWithOpaqueBackground()
11        appearance.backgroundColor = .white
12        appearance.titleTextAttributes = [
13            .foregroundColor: UIColor.systemBlue
14        ]
15        appearance.largeTitleTextAttributes = [
16            .foregroundColor: UIColor.systemBlue
17        ]
18
19        navigationController?.navigationBar.standardAppearance = appearance
20        navigationController?.navigationBar.scrollEdgeAppearance = appearance
21    }
22}

This sets both regular and large title colors consistently.

SwiftUI Integration Case

If your app uses SwiftUI with a navigation stack, you can still configure UIKit appearance in app startup.

swift
1import SwiftUI
2
3@main
4struct DemoApp: App {
5    init() {
6        let appearance = UINavigationBarAppearance()
7        appearance.configureWithDefaultBackground()
8        appearance.titleTextAttributes = [.foregroundColor: UIColor.red]
9        appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.red]
10
11        UINavigationBar.appearance().standardAppearance = appearance
12        UINavigationBar.appearance().scrollEdgeAppearance = appearance
13    }
14
15    var body: some Scene {
16        WindowGroup {
17            NavigationStack {
18                Text("Home")
19                    .navigationTitle("Dashboard")
20            }
21        }
22    }
23}

Global appearance is convenient, but be careful if different screens need different branding.

Legacy and Screen-Specific Customization

For older codebases, you might see direct title text attributes on navigationBar.

swift
navigationController?.navigationBar.titleTextAttributes = [
    .foregroundColor: UIColor.black
]

This still works, but does not fully cover modern large-title scenarios as cleanly as appearance objects.

For screen-specific style, apply appearance in viewWillAppear and restore defaults in viewWillDisappear to avoid leaking styles to other controllers.

Debugging Inconsistent Title Colors

If color changes do not appear:

  • verify the view controller is embedded in a navigation controller
  • check whether large titles are enabled and style both title variants
  • ensure another appearance assignment is not overriding your settings later

A useful trick is placing breakpoints on appearance assignment lines to confirm execution order.

Coordinating Title Color with Other Navigation Elements

Title color should be designed together with bar button tint, background color, and status bar style. If only title color changes, visual contrast can become inconsistent.

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

This keeps title and button colors readable against the same background.

Testing Across Presentation Modes

Navigation bars can appear in pushed screens, modal navigation stacks, and split views. Test all contexts to ensure appearance rules apply consistently.

A practical approach is creating screenshot tests for light mode, dark mode, and large-title states. Visual tests quickly reveal when a later style change accidentally overrides your intended title color.

When teams own separate feature modules, define a shared navigation style helper so each module does not reimplement appearance setup differently. Centralization reduces subtle style drift across screens.

Common Pitfalls

A common pitfall is setting only titleTextAttributes but forgetting largeTitleTextAttributes, which causes mismatched colors when scrolling.

Another issue is mixing global and local appearance changes without clear ownership. Final style becomes order-dependent and hard to maintain.

Developers also set colors before navigation controller exists, so assignments do nothing.

Finally, remember dark mode and contrast. A color that looks good on one background may fail accessibility checks on another.

Summary

  • Use UINavigationBarAppearance for consistent title color behavior in modern iOS.
  • Style both regular and large title attributes.
  • Apply global appearance carefully when screens need distinct themes.
  • For per-screen styles, manage lifecycle entry and exit explicitly.
  • Validate appearance in light, dark, and large-title states.

Course illustration
Course illustration

All Rights Reserved.