Malburrito
Malburrito

Reputation: 1198

SwiftUI: How to “deep-link” to the second/third level of a list in a navigation view

I recently encountered an issue with "deep-linking" to the third level of a list in a navigation view.

Here is some background:

So far, so easy. Now, here is what I attempt to do (please also refer to the attached illustration):

Now my question is: Is it possible to jump to "View 3" (potentially from anywhere in my application) and still be able to go back to "View 2" and then to "View 1" via the back buttons in the navigation view?

This is view 1:

struct SwiftUIView1: View {
    var body: some View {
        NavigationView {
            VStack {
                List {
                    NavigationLink("Link", destination: SwiftUIView2())
                    Text("TBD")
                    Text("TBD")
                }
                .navigationTitle("View 1")
                Button("Jump to view 3", action: XXX) // <-- What to put here?
            }
        }
    }
}

This is view 2:

struct SwiftUIView2: View {
    var body: some View {
        List {
            NavigationLink("Link", destination: SwiftUIView3())
            Text("TBD")
            Text("TBD")
        }
        .navigationTitle("View 2")
    }
}

This is view 3:

struct SwiftUIView3: View {
    var body: some View {
        Text("Hello world")
        .navigationTitle("View 3")
    }
}

Here is a visualization of what I want to achieve:

enter image description here

I would appreciate any ideas!

Upvotes: 4

Views: 1574

Answers (1)

davidev
davidev

Reputation: 8537

Not the best solution, but if you want to achieve a deep link and still be able to go back to #2 and then #1, you might try this solution.

It automatically goes from #1 to #3, however through #2. Otherwise you will not be able to get a back button and go back to #2. That's not possible as it is the default Navigation behaviour...

class NavigationManager: ObservableObject {
    @Published var goToThird: Bool = false
}

struct ContentView: View {
    @State var isActive: Bool = false
    var navigationManager = NavigationManager()
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    NavigationLink("Link", destination: SwiftUIView2(manager: navigationManager), isActive: $isActive)
                    Text("TBD")
                    Text("TBD")
                }
                .navigationTitle("View 1")
                Button("Jump to view 3", action: {
                    isActive = true
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                        navigationManager.goToThird = true
                    }
                }) // <-- What to put here?
            }
        }
    }
}

struct SwiftUIView2: View {
    @ObservedObject var manager: NavigationManager

    var body: some View {
        List {
            NavigationLink("Link", destination: SwiftUIView3(), isActive: $manager.goToThird)

            Text("TBD")
            Text("TBD")
        }
        .navigationTitle("View 2")
    }
}

struct SwiftUIView3: View {
    var body: some View {
        Text("Hello world")
        .navigationTitle("View 3")
    }
}

Upvotes: 1

Related Questions