0

I have a navigation view and each NavigationLink jumps to a color view:

struct ContentView: View {
    private let navigationLinks: [NavigationItem] = [
        NavigationItem("Red", AnyView(Color.red.edgesIgnoringSafeArea(.all))),
        NavigationItem("Orange", AnyView(Color.orange.edgesIgnoringSafeArea(.all))),
        NavigationItem("Yellow", AnyView(Color.yellow.edgesIgnoringSafeArea(.all))),
        NavigationItem("Green", AnyView(Color.green.edgesIgnoringSafeArea(.all))),
        NavigationItem("Blue", AnyView(Color.blue.edgesIgnoringSafeArea(.all))),
        NavigationItem("Purple", AnyView(Color.purple.edgesIgnoringSafeArea(.all))),
        NavigationItem("Pink", AnyView(Color.pink.edgesIgnoringSafeArea(.all))),
        NavigationItem("Cyan", AnyView(Color.cyan.edgesIgnoringSafeArea(.all))),
        NavigationItem("Teal", AnyView(Color.teal.edgesIgnoringSafeArea(.all))),
        NavigationItem("Black", AnyView(Color.black.edgesIgnoringSafeArea(.all))),
        NavigationItem("Gray", AnyView(Color.gray.edgesIgnoringSafeArea(.all))),
    ]
    
    var body: some View {
        NavigationView {
            ForEach(self.navigationLinks, id:\.key) { item in
                NavigationLink(destination: item.value) {
                    Text(item.key)
                }
            }
        }
    }
}

struct NavigationItem {
    let key: String
    let value: AnyView
    init(_ key: String, _ value: AnyView) {
        self.key = key
        self.value = value
    }
}

The result of running the program is just an Orange Item, and the other NavigationItems have disappeared. enter image description here

When I click the back button in the upper left corner it will go back to the Red Item. enter image description here enter image description here

Is there any work around for this?

Janyee
  • 104
  • 8
  • Don’t use AnyView – lorem ipsum Sep 17 '22 at 11:16
  • Do you have a better way? If I don't use AnyView, how can NavigationItem.value receive any type of view? I have tried generics: NavigationItem { let key: String let value: T init(_ key: String, _ value: T) { self.key = key self.value = value } } But initializing the navigationLinks array causes a compile error. @loremipsum – Janyee Sep 17 '22 at 12:36
  • let navigationLinks = [ NavigationItem("Red", Color.red.edgesIgnoringSafeArea(.all)), NavigationItem("Orange", Color.orange.edgesIgnoringSafeArea(.all)) ] ; Error message: Property definition has inferred type '[NavigationItem]', involving the 'some' return type of another declaration. @loremipsum – Janyee Sep 17 '22 at 12:38
  • Watch demytifying SwiftUI, any setup that requires AnyView is a bad setup. – lorem ipsum Sep 17 '22 at 12:48

1 Answers1

1

Your current ForEach will directly add all Text to NavigationView and this makes NavigationView confused. Wrap your ForEach to either List or VStack.

List { //Or VStack {
    ForEach(self.navigationLinks, id:\.key) { item in
        NavigationLink(destination: item.value) {
            Text(item.key)
        }
    }
}

Note: With VStack you don't have scroll so if you are planning to add more items or a dynamic list then it's better to use List View only.

Nirav D
  • 71,513
  • 12
  • 161
  • 183