TokamakUI / Tokamak

SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms
Apache License 2.0
2.62k stars 111 forks source link

Add item in collection property wrapper support #521

Open Sammcb opened 2 years ago

Sammcb commented 2 years ago

Describe the bug In SwiftUI 3, support was added for using a binding of an element in a collection.

struct ExampleView: View {
  @State var directions: [Direction] = [SomeIdentifiableStructWithFields()]

  var body: some View {
    List($directions) { $direction in
      TextField("Instructions", text: $direction.text)
      Text(direction.text)
    }
  }
}

This allows for using a binding to a value and reading the value. Currently this behavior is not supported in Tokamak. In the example above, I get an error on $direction in saying

Cannot use property wrapper projection parameter

This isn't a big issue since you can technically use a ForEach on the count and index into the collection, but would be a nice to have!

Expected behavior Using a binding would work in the above code snippet.

Desktop (please complete the following information):

Thanks!

davdroman commented 1 year ago

The reason is that State must declare init(projectedValue: Binding<Value>).

Property wrappers can enable passing a projected-value argument to a property-wrapped parameter by declaring var projectedValue, and implementing an init(projectedValue:) that meets the following requirements: [...]

Source: https://github.com/apple/swift-evolution/blob/main/proposals/0293-extend-property-wrappers-to-function-and-closure-parameters.md#passing-a-projected-value-argument