SwiftUI.cc
Snippets
NavigationNavigation BarBeginner

SwiftUI NavigationStack Titles and Bar Customization

NavigationStack hosts push navigation. Configure titles and display modes, place bar items with toolbar, and control bar background and visibility with toolbarBackground.

5 min readUpdated 2026-06
Branded bar with toolbar actions
import SwiftUI

struct TripsScreen: View {
    var body: some View {
        NavigationStack {
            List(1...10, id: \.self) { n in
                NavigationLink("Trip \(n)", value: n)
            }
            .navigationDestination(for: Int.self) { n in
                Text("Trip \(n) details")
            }
            .navigationTitle("Trips")
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Add", systemImage: "plus") { }
                }
            }
            .toolbarBackground(.teal.opacity(0.2), for: .navigationBar)
            .toolbarBackground(.visible, for: .navigationBar)
        }
    }
}

NavigationStack bar customization preview

Titles belong to screens

NavigationStack is the container, but every pushed view declares its own navigationTitle. Display modes: .large for browsing roots, .inline for dense detail screens — .large collapses to inline automatically as the user scrolls.

Toolbar placements

toolbar { } positions items semantically: .topBarLeading, .topBarTrailing, .principal (center), .bottomBar, and .confirmationAction/.cancellationAction inside sheets. Semantic placements let the system adapt across platforms.

.toolbar {
    ToolbarItem(placement: .principal) { Logo() }
    ToolbarItemGroup(placement: .bottomBar) {
        Button("Filter", systemImage: "line.3.horizontal.decrease") {}
        Spacer()
        Button("Sort", systemImage: "arrow.up.arrow.down") {}
    }
}

Bar appearance

toolbarBackground(_:for:) sets a color, gradient, or material; pair it with toolbarBackground(.visible, for: .navigationBar) so it shows even before content scrolls underneath. toolbar(.hidden, for: .navigationBar) removes the bar for immersive screens, and toolbarColorScheme(.dark, for: .navigationBar) flips title color over dark brand backgrounds.

Back button control

navigationBarBackButtonHidden(true) suppresses the chevron — used for confirmation gates and custom back designs. Re-create the affordance with a .topBarLeading item and remember the edge-swipe gesture follows the system button's presence.

Common mistakes

  • Titling the NavigationStack instead of the screens inside it.
  • Setting toolbarBackground without .visible and concluding it does not work.
  • Nesting NavigationStacks accidentally, producing double bars.

Related reference