How can I properly add multiple NavigationStack's to the many detail View's of my main NavigationSplitView

162 views Asked by At

I am trying to add NavigationStack's to the detail View's of my main NavigationSplitView. I have seen simplistic examples of how to achieve this with static lists that don't require any information passed to them. In my example below I want to be able to pass data to my view's based on which row they press in the NavigationStack of the detail view. I have tried to create separate enums to handle navigation in the different Detail View's however I get the error:

SwiftUI.AnyNavigationPath.Error.comparisonTypeMismatch

so I have only one main enum to handle all navigation in my app. But then using this approach I am unable to pass data in the navigationLink:

enum NavPath: Hashable {
    case colors
    case words
}


struct ContentView: View {
    
    enum AppScreen: String, Identifiable {
        case firstView = "First View"
        case secondView = "Second View"
        
        var id: AppScreen { self }
    }
    
    @State private var selection: AppScreen?
    
    let appScreens: [AppScreen] = [AppScreen.firstView, AppScreen.secondView]
    
    var body: some View {
        NavigationSplitView {
            List(selection: $selection) {
                ForEach(appScreens) { screen in
                    NavigationLink(value: screen) {
                        Text(screen.rawValue)
                    }
                }
            }
        } detail: {
            switch self.selection {
            case .firstView:
                FirstView()
            case.secondView:
                SecondView()
            default:
                EmptyView()
            }
        }
    }
}

struct FirstView: View {
    
    let colors: [Color] = [.red, .yellow, .green, .blue]
    @State var path: [NavPath] = []
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(colors, id: \.self) { color in
                    NavigationLink(value: NavPath.colors) {
                        Text(color.description)
                    }
                }
            }
            .navigationDestination(for: NavPath.self) { value in
                if value == .colors {
                    ColorView(color: .red)  // how do I pass the dynamically selected color
                }
            }
        }
    }
}

struct SecondView: View {
    
    let words: [String] = ["Red", "Yellow", "Green", "Blue"]
    @State var path: [NavPath] = []
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(words, id: \.self) { word in
                    NavigationLink(value: NavPath.words) {
                        Text(word)
                    }
                }
            }
            .navigationDestination(for: NavPath.self) { value in
                if value == .words {
                    WordView(word: "Red")  // how do I pass the dynamically selected color
                }
            }
        }
    }
}

struct WordView: View {
    var word: String
    var body: some View {
        Text(word)
    }
}

struct ColorView: View {
    var color: Color
    var body: some View {
        color
    }
}

In the example above I have hard coded the argument which is obviously not what is needed here.

It seems I am taking the wrong approach. Wondering what is the correct way to handle navigation in Detail View's of NavigationSplitView's

0

There are 0 answers