3

How do I pass a Binding via the new .navigationDestination(for: , destination: )?

import SwiftUI

enum TestEnum: String, Hashable, CaseIterable {
    case first, second, third
}

struct ContentView: View {
    
    @State private var test: TestEnum = .first

    var body: some View {
        NavigationStack {
            VStack {
                NavigationLink(value: test, label: {
                    Text(test.rawValue)
                })
            }
            // This does not work, as it won't allow me to use $caze
            .navigationDestination(for: TestEnum.self, destination: { caze in
                SecondView(test: $caze)
            })
        }
    }
}

struct SecondView: View {
    
    @Environment(\.presentationMode) var presentationMode
    @Binding var test: TestEnum
    
    var body: some View {
        ForEach(TestEnum.allCases, id: \.self) { caze in
            Button(action: {
                test = caze
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Text(caze.rawValue)
            })
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

In SwiftUI 3.0 I'd simply use:

NavigationLink(destination: SecondView(test: $test), label: {
   Text(test.rawValue)
})

Is this still the correct approach, as we cannot pass a Binding yet?

Not really interested in complex workarounds like using an EnvironmentObject and passing an index, as the SwiftUI 3.0 approach works fine.

However, if there is a proper way of passing a Binding via .navigationDestination(for: , destination: ) I'll happily use it.

4
  • 1
    I think there is nothing wrong with using NavigationLink(destination: SecondView(test: $test), label: { Text(test.rawValue) }) with the NavigationStack instead of the navigationDestination. NavigationView is deprecated but not NavigationLink(destination: ..) Nov 1, 2022 at 1:39
  • 1
    There is no "proper" way that isn't what you are using now. Binding isn't Hashable Nov 1, 2022 at 1:47
  • Supposing that one actually needs to use .navigationDestination with a Binding, for example in a programmatic navigation with bound properties... Is there a way to make Binding<Stuff> Hashable? Nov 24, 2022 at 18:14
  • 1
    The problem I found with using NavigationLink(destination:label:) is that it does not add the destination to the Navigation Stack path. Mar 18, 2023 at 21:25

1 Answer 1

-2

According to this doc:

https://developer.apple.com/documentation/charts/chart/navigationdestination(for:destination:)/

[WRONG: Where destination get passed from NavigationLink, but in the doc they use the NavigationLink("Mint", value: Color.mint) version of the NavigationLink. I don't know if this make any difference.

You are using the NavigationLink(value:label:)]

EDIT: I insist, after further investigation, that you are using the ViewModifier wrong.

Read the doc that I pointed above. The viewModifier signature is:

func navigationDestination<D, C>(
    for data: D.Type,
    destination: @escaping (D) -> C
) -> some View where D : Hashable, C : View

Note D is Hashable, not State

So, when you pass $caze you are not passing the @State var above, but the NavigationLink(value: test... that is not a @State wrapper. Is the generic D ... a single value, so $caze is not a Binding to the State.

You can pass normally $test, from that is a Binding to the State test. But the parameter inside the closure .navigationDestination( value in ... is not.

2
  • Your answer is completely unrelated to the question. Also, NavigationLink("", value:) is the simplified version of NavigationLink(value:label:). The former has a simple Text and the latter can be a complex view for the NavigationLink’s label. Nov 1, 2022 at 0:55
  • Sorry for trying to answer you. I did my best. Nov 1, 2022 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.