SwiftUI 4.0: NavigationStack second Subview, movement and back link broken

Viewed 262

I'm using NavigationStack and struggling with Navigationslinks on second SubView depth.


struct ContentView: View {
    var body: some View {
        NavigationStack {
            VStack {
                Text("I'm a MainView").font(.title2).padding()
                NavigationLink {
                    SubChild1()
                } label: {
                    Text("Goto SubView 1").font(.title3)
                }
                Spacer()
            }
        }
    }
}


struct SubChild1: View {
    var body: some View {
        VStack {
            Text("I'm SubView 1").font(.title2)
            .padding()
            NavigationLink {
                SubChild2()
            } label: {
                    Text("Goto SubView 2").font(.title3)
            }
            Spacer()
        }
    }
}

struct SubChild2: View {
    var body: some View {
        VStack {
            Text("I'm a SubView 2").font(.title2).padding()
            Spacer()
        }
    }
}

When I navigate to Subview 1, animation work. If I navigate then to Subview2 the view appear immediately without animation. The "Back" link on upper left corner navigates back to the root main view controller instead of subview 1. Did I miss something or is that a known "feature"?

1 Answers

So after some testing. If I change to:

enum Links: Hashable {
    case sub1, sub2, others
}

struct ContentView: View {
    let links = Links.sub1
    
    var body: some View {
        NavigationStack {
            VStack {
                Text("I'm a MainView").font(.title2).padding()
                
                NavigationLink(value: Links.sub1) {
                    Text("Goto SubView 1").font(.title3)
                }
                .navigationDestination(for: Links.self) { link in
                    switch link {
                    case .sub1:
                        SubChild1()
                    case .sub2:
                        SubChild2()
                    default:
                        Text("You reached the end of all Views")
                    }
                }
            }
            Spacer()
        }
    }
}



struct SubChild1: View {
    var body: some View {
        VStack {
            Text("I'm SubView 1").font(.title2)
                .padding()
            NavigationLink(value: Links.sub2) {
                Text("Goto SubView 2").font(.title3)
            }
            .padding(.bottom,20)
            NavigationLink(value: Links.others) {
                Text("End of all Views").font(.title3)
            }
            .navigationDestination(for: Links.self) { link in
                switch link {
                case .sub1:
                    SubChild1()
                case .sub2:
                    SubChild2()
                default:
                    Text("You reached the end of all views")
                }
            }
            Spacer()
        }
    }
}

struct SubChild2: View {
    var body: some View {
        VStack {
            Text("I'm a SubView 2").font(.title2).padding()
            Spacer()
        }
    }
}

The navigation works now as expected, but I'have to implement an D.Type eg. Enum with a case for every link.

Using e.g. one case doesn't work and on console I get the message on subview1:

A navigationDestination for “NavigationStackDemo.Links” was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used.

and instead of subview2 is added subview1 is added as destination.

Related