Why pop to root does not work in this sample code SwiftUI?

Viewed 177

For the purpose of this question, I have provided minimum sample code to re-create the bug. Just copy/paste it to run.

import SwiftUI

final class Popper: ObservableObject {
    @Published var shouldProceed: String? = nil
    var id: String
    init(id: String) { self.id = id }
}

struct ContentView: View {
    @StateObject var popper = Popper(id: "ROOT")
    
    var body: some View {
        NavigationView {
            VStack(spacing: 40) {
                Text("You are now in ROOT").font(.largeTitle)
                Text("Tap Here to goto V1").onTapGesture {
                    popper.shouldProceed = "y"
                }.foregroundColor(.blue)
                NavigationLink(destination: V1().environmentObject(popper),
                               tag: "y",
                               selection: $popper.shouldProceed) {
                    EmptyView()
                }
            }
        }
    }
}

struct V1: View {
    @EnvironmentObject var rootPopper: Popper
    @StateObject var v1Popper = Popper(id: "V1")
    var body: some View {
        VStack(spacing: 40) {
            Text("You are now in V1").font(.largeTitle)
            Text("Tap Here to pop to root").onTapGesture {
                print("popping to: \(rootPopper.id)")
                rootPopper.shouldProceed = nil
            }.foregroundColor(.red)
            
            Text("Or tap here to go to V2").onTapGesture {
                v1Popper.shouldProceed = "y"
            }.foregroundColor(.blue)
            NavigationLink(destination: V2().environmentObject(v1Popper),
                           tag: "y",
                           selection: $v1Popper.shouldProceed) {
                EmptyView()
            }
            
        }
    }
}

struct V2: View {
    @EnvironmentObject var v1Popper: Popper
    @State var shouldProceed: String? = nil
    var body: some View {
        VStack(spacing: 40) {
            Text("You are now in V2").font(.largeTitle)
            Text("Tap Here to pop to V1").onTapGesture {
                print("popping to: \(v1Popper.id)")
                v1Popper.shouldProceed = nil
            }.foregroundColor(.red)
            
            Text("Or Tap here to gotoV3").onTapGesture {
                shouldProceed = "y"
            }.foregroundColor(.blue)
            NavigationLink(destination: V3().environmentObject(v1Popper),
                           tag: "y", selection: $shouldProceed) {
                EmptyView()
            }
            
        }
    }
}

struct V3: View {
    @EnvironmentObject var v1Popper: Popper
    var body: some View {
        VStack(spacing: 40) {
            Text("You are now in V3").font(.largeTitle)
            
            Text("Tap Here to pop to V1").onTapGesture {
                print("popping to: \(v1Popper.id)")
                v1Popper.shouldProceed = nil
            }.foregroundColor(.red)
        }
    }
}

Question When you get to screen V3, why does it not pop to the V1 screen? All the other pop functions work. It just fails for some reason when it gets to screen V3. Please help.

1 Answers

Try to use .isDetailLink(false) for your links, like

NavigationLink(destination: V1().environmentObject(popper),
               tag: "y",
               selection: $popper.shouldProceed) {
    EmptyView()
}.isDetailLink(false)     // << here !!
Related