NavigationView: basics, navigation stack in SwiftUI apps

Author: IT Sectr Published: 2026-02-22 Reading time: 6 min

NavigationView is a SwiftUI container component for organizing stack-based navigation between screens. NavigationView creates a navigation stack with an automatic navigation bar, title, and back button. Since iOS 16, Apple recommends using NavigationStack. Read more in Apple documentation.

Key Takeaways

  • NavigationView — SwiftUI container for stack navigation, creates navigation bar and back button
  • NavigationLink — element for transitioning to a new screen inside NavigationView
  • NavigationStack — successor to NavigationView (iOS 16+) with programmatic stack management
  • .toolbar — modifier for adding buttons to the navigation bar
  • .navigationTitle — sets the screen title in large or inline style

What is NavigationView?

NavigationView is a SwiftUI container that wraps a hierarchy of screens and provides a navigation interface. Inside NavigationView, NavigationLink works — an element that replaces the current screen with a new one when pressed. NavigationView automatically adds a navigation bar with a title and a back button.

NavigationView was introduced in iOS 13 alongside SwiftUI. Conceptually, it replaces UINavigationController from UIKit but is implemented declaratively. Instead of manual push/pop, the developer describes the relationship between screens using NavigationLink. The system automatically manages the stack.

NavigationView supports modifiers .navigationTitle, .navigationBarTitleDisplayMode, .toolbar and .searchable. For iOS 16+, Apple introduced NavigationStack, which preserves the NavigationView API but adds programmatic stack management via NavigationPath. For projects supporting iOS 15 and below, NavigationView remains the only option.

NavigationLink is a SwiftUI element that creates a transition to a target screen inside NavigationView or NavigationStack. When NavigationLink is pressed, the system adds the target screen to the navigation stack. The transition animation is the standard push from the right on iOS, adapting to the platform.

swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            List(items) { item in
                NavigationLink(destination: DetailView(item: item)) {
                    Text(item.title)
                }
            }
            .navigationTitle("List")
        }
    }
}

struct DetailView: View {
    let item: Item

    var body: some View {
        VStack {
            Text(item.description)
                .navigationTitle(item.title)
                .navigationBarTitleDisplayMode(.inline)
        }
    }
}

NavigationLink takes two parameters: destination — the target View, and label — the element the user presses. For lists, the syntax with value and NavigationLink(value:) is convenient — it automatically unselects the cell and works with NavigationPath.

With iOS 16, Apple introduced NavigationStack as a replacement for NavigationView. NavigationStack preserves the declarative syntax but adds a critically important feature — programmatic stack management through the path property of type NavigationPath or an array of Hashable.

FeatureNavigationView (iOS 13-15)NavigationStack (iOS 16+)
Programmatic pushNo, only via NavigationLinkYes, via path.append(value)
popToRootOnly dismiss to rootpath.removeLast(path.count)
Deep LinksComplex implementationBuilt-in support via path
Stack typingNo (any View in destination)Yes (array of Hashable values)
iPad SplitViewColumnStyle / StackStyleNavigationSplitView (iOS 16+)

For projects with a minimum version of iOS 16+, use NavigationStack. For iOS 14-15 support — NavigationView. NavigationStack has no direct analogs for older versions, so upgrading requires compatibility checking.

Toolbar and navigationTitle Configuration

The .toolbar and .navigationTitle modifiers control the content of the navigation bar. .navigationTitle sets the screen title, .navigationBarTitleDisplayMode selects the style: .large (prominent, default) or .inline (compact, like in Settings). .toolbar adds buttons, search, and segmented control.

swift
struct SettingsView: View {
    var body: some View {
        NavigationStack {
            Form {
                Section("Profile") {
                    Text("Username")
                    Toggle("Notifications", isOn: $notifications)
                }
            }
            .navigationTitle("Settings")
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Save") { save() }
                }
                ToolbarItem(placement: .navigationBarLeading) {
                    EditButton()
                }
            }
        }
    }
}

.searchable is another modifier that integrates a search bar into the navigation bar. Works with both NavigationView and NavigationStack. The search bar automatically hides when scrolling and appears when swiping down. Supports list filtering via a Binding String.

Programmatic Navigation with NavigationPath

NavigationPath is an iOS 16+ type that represents a navigation stack as a collection of Hashable values. The developer adds elements to path for programmatic transitions, removes them for returning. NavigationPath supports deep links, push notifications, and state restoration.

swift
struct AppNavigation: View {
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            List(categories) { category in
                NavigationLink("Category \(category.name)",
                               value: category)
            }
            .navigationTitle("Categories")
            .navigationDestination(for: Category.self) { category in
                ProductListView(category: category)
            }
            .navigationDestination(for: Product.self) { product in
                ProductDetailView(product: product)
            }
        }

        // Programmatic deep link navigation
        .onOpenURL { url in
            guard let productId = DeepLinkParser.parse(url) else { return }
            path.append(Product(id: productId))
        }
    }
}

.navigationDestination(for:) registers a data type for which to show a screen. When a value of this type is added to the path, the system automatically creates the target View. This approach replaces explicit NavigationLink(destination:) and makes navigation strictly typed.

NavigationView and NavigationStack work on all Apple platforms: iOS, iPadOS, watchOS, tvOS and macOS. Behavior adapts to the screen. On iPad, NavigationStack supports NavigationSplitView, which replaces UISplitViewController from UIKit and displays two columns on a wide screen.

NavigationSplitView (iOS 16+) splits the screen into sidebar (list) and detail. On iPhone, the sidebar is hidden, showing only detail via NavigationLink. On iPad, sidebar and detail are displayed simultaneously in split mode.

swift
struct AdaptiveNavigation: View {
    @State private var selectedCategory: Category?

    var body: some View {
        NavigationSplitView {
            List(categories, selection: $selectedCategory) { category in
                Text(category.name)
            }
            .navigationTitle("Categories")
        } detail: {
            ProductListView(category: selectedCategory)
        }
    }
}

NavigationSplitView automatically selects the optimal display mode for each device. On iPhone in portrait — stack, on iPad and iPhone in landscape — split. The developer doesn't need to write separate code for different size classes.

Frequently Asked Questions

What is the difference between NavigationView and NavigationStack?

NavigationView is the old API (iOS 13-15), supports only declarative NavigationLink. NavigationStack is the new API (iOS 16+), adds path for programmatic navigation, deep links and a strictly typed stack. NavigationStack is recommended by Apple for new projects.

How to add a button to the navigationBar?

Through the .toolbar modifier with ToolbarItem. For example: .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('Settings') { } } }. Placement determines the position: trailing (right), leading (left), principal (center).

How to configure the title and its style?

The title is set via .navigationTitle('Title'). Style — .navigationBarTitleDisplayMode(.large) or .inline. Large — prominent title in iOS Music style, inline — compact, like in Settings. The style can be changed for each screen individually.

How to pass data through NavigationLink?

Three ways: via value (NavigationLink(value:item) { Label }, iOS 16+), via destination + label, via isActive for programmatic transition. NavigationLink with value is cleaner for lists as it doesn't require creating the target View before the transition.

Can NavigationView be used on watchOS and tvOS?

Yes. NavigationView and NavigationStack are available on iOS, iPadOS, watchOS, tvOS and macOS. On watchOS navigation uses the interface hierarchy with the Digital Crown, on tvOS — focus-based input with the remote. Behavior adapts to the platform automatically.

Summary

  • NavigationView — SwiftUI container for stack navigation with automatic navigation bar and back button
  • NavigationLink — the main transition element, supports declarative (destination) and value-based syntax
  • NavigationStack (iOS 16+) replaces NavigationView, adding programmatic stack management via NavigationPath
  • .toolbar adds buttons to the navigation bar, .navigationTitle sets the title with large/inline style selection
  • NavigationPath — strictly typed stack of Hashable values for programmatic navigation and deep links
  • NavigationSplitView (iOS 16+) adapts the interface for iPad and iPhone, automatically choosing split or stack
  • The choice between NavigationView and NavigationStack is determined by the minimum supported iOS version in the project

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also