How to have the value of a key value pair in a dictionary used as a binding value to another view like a Stepper

Viewed 274

I would think this should be pretty simple but I am getting an error saying that Int is not Hashable.

import SwiftUI

struct ContentView: View {
    @State var testNumbers : [String : Int] = ["foo" : 1]
    var body: some View {
        Stepper("test", value: $testNumbers["foo", default: 1])
    }
}

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

Error message:

Subscript index of type '() -> Int' in a key path must be Hashable

2 Answers

Binding doesn't have any Dictionary-like subscripts built-in, so you'll need to make your own.

public extension Binding {
  subscript<Key, Value_Value>(
    key: Key,
    default default: Value_Value
  ) -> Binding<Value_Value>
  where Value == [Key: Value_Value] {
    .init(
      get: { wrappedValue[key, default: `default`] },
      set: { wrappedValue[key] = $0 }
    )
  }
}

I use the stupid-looking-but-decent-compromise name Value_Value because Self.Value can't be used yet.

You can use a custom Binding to create a variable of type Binding <Int> which is needed in the Stepper:

struct ContentView: View {
    @State var testNumbers: [String: Int] = ["foo": 1]

    var binding: Binding<Int> {
        .init(get: {
            testNumbers["foo", default: 1]
        }, set: {
            testNumbers["foo"] = $0
        })
    }

    var body: some View {
        Stepper("test", value: binding)
    }
}
Related