3

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
    NavigationStack isn't a view - did you mean NavigationView? – Gavin Morrow Jul 18 '22 at 16:36
  • Also, I can't reproduce this. MacOS Monterey 12.4 (21F79), Xcode 13.4.1 (13F100), Simulator 13.4.1 (977.2), iOS 15.5 on an iPhone 13 mini. – Gavin Morrow Jul 18 '22 at 16:39
  • 5
    @ProgrammerG, did you sleep on WWDC22 or missed it? It is for Xcode 14 / iOS 16 folks... ;) – Asperi Jul 18 '22 at 16:45
  • 1
    @macventure, it looks like a bug, you can file a feedback to Apple. Meanwhile as you decided to use new `NavigationStack`, then try to use new `NavigationLink(_ , value:)` + `.navigationDestination` - new things work better together, at least as far as I tested (see updated part of https://stackoverflow.com/a/59404821/12299030). – Asperi Jul 18 '22 at 17:02
  • @ProgrammerG it is a view. You need to update your macOS and Xcode to run this. – Steven-Carrot Jul 18 '22 at 17:03
  • @ProgrammerG you can't reproduce this as `NavigationStack` is still in **Βeta** released with **iOS 16 wwdc22**. – Timmy Jul 18 '22 at 17:21
  • 1
    Oh ok I didn’t know that. Sorry ‍♂️ – Gavin Morrow Jul 18 '22 at 17:32
  • @ProgrammerG sorry for the confusion, with SwiftUI 4.0 I meant Beta iOS16. – rotecodefraktion Jul 18 '22 at 20:06
  • @Asperi I thought the migration from NavigationView to NavigationStack doesn't need change in NavigationLink calls. – rotecodefraktion Jul 18 '22 at 20:06
  • 1
    Actually you're right and none of NavigationLink inits has deprecated, and I wrote about a bug, but... you know... :) – Asperi Jul 18 '22 at 20:11

1 Answers1

1

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.