4

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

Here is some background:

  • My app has a settings menu that is based on SwiftUI lists/forms
  • As typical for a menu you can jump from one list item to the next list (one level "deeper") - this is realized NavigationLink
  • Because the list on the top level is embedded in a navigation view, SwiftUI automatically adds a "back" button to the child views on the lower levels to get back to the first menu page

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

  • I want to jump from the first view (potentially also from other unrelated views) directly to as sub-menu; i.e. a list that is on the second or third level of my menu
  • What I did so far is to set a programmatic navigation link that links directly to what is named "View 3" in the illustration. However, this does not provide the possibility to jump back to "View 2" and then to "View 1" via the back buttons in the navigation view

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!

Malburrito
  • 860
  • 7
  • 23

1 Answers1

1

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")
    }
}
davidev
  • 7,694
  • 5
  • 21
  • 56