Why the need to convert SwiftUI Binding<Hashable> to Binding<AnyHashable>?

SwiftUI Binding has this:

init<V>(_ base: Binding<V>) where Value == AnyHashable, V : Hashable

Its doc:

Creates a binding by projecting the base value to a hashable value.

I don't understand what this mean. But it converts a Binding<Hashable> to Binding<AnyHashable>. Why is this need? What are some examples demonstrating the need to use Binding<AnyHashable>?

Since you can just write generic over Hashable, I'm just not seeing any need for AnyHashable:

Generic of Binding<V: Hashable>
import SwiftUI

struct BindingHashableToBindingAnyHashable: View {

    // with generic, there is no need to type erase Hashable to AnyHashable
    func foo<V: Hashable>(@Binding arg: V, value: V) {
        arg = value
    }

    @State private var int = Int.zero
    @State private var double = Double.zero
    @State private var string = "Hello, World!"

    var body: some View {
        VStack {
            Text("int = \(int)")
            Button("Random Int") {
                foo($arg: $int, value: Int.random(in: 0...100))
            }
            Text("double = \(double)")
            Button("Random Double") {
                foo($arg: $double, value: Double.random(in: 0...100))
            }
            Text("string = \(string)")
            Button("Random String") {
                foo($arg: $string, value: ["One", "Two", "Three"].randomElement()!)
            }
        }
    }
}

struct BindingHashableToBindingAnyHashable_Previews: PreviewProvider {
    static var previews: some View {
        BindingHashableToBindingAnyHashable()
    }
}

So this is type erase some Hashable to AnyHashable in a binding. But you still need to know what the original type was when setting value to Binding<AnyHashable>, if not the right type, it just crash.

There must be case where Binding<AnyHashable> is required? Please fill me in!

Edit: I think Binding<AnyHashable> enable this:

bindingOfAnyHashable = someAnyHashable   // directly assign an AnyHashable, letting the binding do casting internally

But since AnyHashable has magic to allow directly cast to its original type:

@State var number = 0
...
// can just do this to assign from an AnyHashable
$number = someAnyHashable as! Int   // assuming this AnyHashable holds an Int, can just cast

No need to go from a Binding<Int> to Binding<AnyHashable>.

Terms of Service

Privacy Policy

Cookie Policy