Wesley de Groot's Blog
NavigationStack

Back

NavigationStack is a framework that provides a navigation stack for macOS and iOS.
Navigation was done using NavigationView, but it was deprecated in iOS 16 and was split into two new containers, NavigationStack and NavigationSplitView, and each one of them has new features.

What is NavigationStack?

NavigationStack is a way to manage navigation within a SwiftUI application.
It provides a stack-based navigation system that allows you to push and pop views onto and off of the navigation stack.
This makes it easy to create complex navigation flows in your application.

Requirements

iOS 16.0+, iPadOS 16.0+, Mac Catalyst 16.0+, macOS 13.0+, tvOS 16.0+, visionOS 1.0+, watchOS 9.0+

Key Features of NavigationStack

  1. Declarative Syntax: Like all SwiftUI components, NavigationStack uses a declarative syntax, making it easy to define the navigation flow in your app.
  2. State Management: It integrates seamlessly with SwiftUI's state management, allowing you to control the navigation stack based on your app's state.
  3. Custom Transitions: You can customize the transitions between views, providing a more engaging user experience.
  4. Deep Linking: NavigationStack supports deep linking, enabling users to navigate directly to specific views within your app.

Navigate to a view

With NavigationStack, you can navigate to a view by appending a view to the navigation path.
This can be done programmatically by calling append on the NavigationPath object, or by using a Button or NavigationLink.

Button("Go to profile") {
    navPath.append("profile") // This will trigger navigationDestination(for: String.self)
    // You can also route it to a specific view by using a specific identifier like "profile/1" (see example 3)
}

Example 1

import SwiftUI

struct ContentView: View {
    @State
    private var navigationPath = NavigationPath()

    var body: some View {
        // For sake of this demo the button is directly in the navigation stack
        NavigationStack(path: $navigationPath) {
            Button("Open view with identifier qwerty") {
               navigationPath.append("qwerty") // This will trigger navigationDestination(for: String.self)
               // if you use a Int, it needs to be Int.self, and so on.
            }
            .navigationDestination(for: String.self) { identifier in
                YourView(withIdentifier: identifier)
            }
        }
    }
}

struct YourView: View {
    var identifier: String

    var body: some View {
        Text("Hello, \(identifier)!")
    }
}

Example 2 with pop to root

import SwiftUI

struct ContentView: View {
    @State
    private var navigationPath = NavigationPath()

    var body: some View {
        // For sake of this demo the button is directly in the navigation stack
        NavigationStack(path: $navigationPath) {
            Button("Open view with identifier qwerty") {
               navigationPath.append("qwerty")
            }
            .navigationDestination(for: String.self) { identifier in
                VStack { 
                    Text("Hello, \(identifier)!")

                    var random = Int.random(in: 0...100)
                    Button("Add view \(random)") {
                        navigationPath.append("Random View \(random)")
                    }
                    Button("Back") {
                        navigationPath.removeLast()
                    }
                    Button("Root View") {
                        navigationPath = NavigationPath()
                    }
                }
            }
        }
    }
}

Example Navigate to a view with a specific identifier

You can also navigate to a view with a specific identifier by appending the identifier to the navigation path.
This can be done programmatically by calling append on the NavigationPath object, or by using a Button or NavigationLink.


import SwiftUI

struct ContentView: View {
    @State
    private var navigationPath = NavigationPath()

    var body: some View {
        // For sake of this demo the button is directly in the navigation stack
        NavigationStack(path: $navigationPath) {
            BButton("Go to profile") {
                navigationPath.append("profile/1") // This will trigger navigationDestination(for: String.self)
            }
            .navigationDestination(for: String.self) { identifier in
                // Note: this is a simple example, in a real app you would probably want to use a switch statement or something similar to handle different identifiers.
                if identifier.hasPrefix("profile/") {
                    let profileID = identifier.replacingOccurrences(of: "profile/", with: "")
                    ProfileView(profileID: profileID)
                }
            }
        }
    }
}

Wrap up

NavigationStack is a powerful tool for managing navigation in your SwiftUI app, especially when you need to use routing and other advanced navigation features.

Credits

I created this article for a friend to help him to navigate in his Alzheimer’s Detection App.

Resources:

Read more

Share


Share Mastodon Twitter LinkedIn Facebook
x-twitter mastodon github linkedin discord threads instagram whatsapp bluesky square-rss sitemap