In my app, I have a main list view with NavigationLink
s to detail views. There is an onURLOpen
modifier on the main view that will change a state selection variable to navigate to the appropriate detail view (using tagged NavigationLinks that are bound to the selection variable).
This works perfectly well as long as the app is on the main list view (the correct detail view will be pushed). However, if the app is already on a different detail view, the app will pop the old detail view, push the correct detail view, but then pop the correct view and end up back on the main view.
GIF of the issue:
This simplified code illustrates the problem:
import SwiftUI
struct ListView: View {
@State private var selection: Int?
var body: some View {
NavigationView {
List {
NavigationLink(
destination: DetailView(selection: $selection),
tag: 1,
selection: $selection) {
Text("Option 1")
}
NavigationLink(
destination: DetailView(selection: $selection),
tag: 2,
selection: $selection) {
Text("Option 2")
}
}
.navigationTitle("Options")
}
}
}
struct DetailView: View {
@Binding var selection: Int?
var body: some View {
ZStack {
switch selection {
case 1:
Button {
selection = 2
} label: {
Text("Go to Option 2")
}
case 2:
Button {
selection = 1
} label: {
Text("Go to Option 1")
}
default:
Text("No option selected")
}
}
.navigationTitle("Option \(selection ?? 0)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ListView()
}
}
Is this expected behavior for NavigationLink
? Is there a better way of doing this? I'd be grateful for any pointers.
So far, I've tried adding extra invisible NavigationLink
s, NavigationLink
with isActive: Binding<Bool>
, the isDetailLink
modifier, and an ObservableObject
instead of a Binding
.
Tested in Xcode 12.5 / iOS 14.5.