Is there a good way to obtain a binding to the associated value of an enum? For now I'm using custom Bindings like this:
However, this seems overly complicated. Also, in the above example, if there are updates to the TextFields triggered by autocorrect, they're not reflected in the accompanying Text, so I suspect that this usage of bindings is not idiomatic.
Code Block swift enum Row { case text(_ body: String) // ... } struct StuffView: View { @State var stuff: [Row] = [.text("foo"), .text("bar")] var body: some View { List { ForEach(stuff.indices) { idx in switch stuff[idx] { case .text(let body): HStack { // want: TextField("Row \(idx)", text: $body) // or TextField("Row \(idx)", text: $stuff[idx].body) TextField( "Row \(idx)", text: Binding( get: { body }, set: { stuff[idx] = .text($0) } ) ) Spacer() Text(body) } } } } } }
However, this seems overly complicated. Also, in the above example, if there are updates to the TextFields triggered by autocorrect, they're not reflected in the accompanying Text, so I suspect that this usage of bindings is not idiomatic.
If you would not mind defining a read-write computed property, you can write something like this:
Code Block extension Row { var textBody: String { get { switch self { case .text(let body): return body default: return "" } } mutating set { self = .text(newValue) } } } struct StuffView: View { @State var stuff: [Row] = [.text("foo"), .text("bar")] var body: some View { List { ForEach(stuff.indices) { idx in switch stuff[idx] { case .text(let body): HStack { TextField( "Row \(idx)", text: $stuff[idx].textBody //<- ) Spacer() Text(body) } } } } } }