I\'m using an ObservableObject \'DataStore\', which contains an array (\'exampleList\') of objects (\'exampleObject\').
@Published exampleList = [exampleObjec
I had to bind the array of an observable object recently, didn't get any warnings on stable XCode11. I did it like this
struct ScheduleTimer: Identifiable {
var id: Int
var name: String
var start: Date
var end: Date
var isActive: Bool
}
struct ScheduleView: View {
@ObservedObject var scheduleController = ScheduleController()
var body: some View {
NavigationView {
Form {
ForEach(scheduleController.timers) { timer in
ScheduleForm(scheduleController: self.scheduleController, timer: timer)
}
}
}
}
}
struct ScheduleForm: View {
@ObservedObject var scheduleController: ScheduleController
var timer: ScheduleTimer
var scheduleIndex: Int {
scheduleController.timers.firstIndex(where: { $0.id == timer.id })!
}
@State var start = Date()
var body: some View {
Section(header: Text(self.scheduleController.timers[scheduleIndex].name)){
DatePicker("From", selection: self.$scheduleController.timers[scheduleIndex].start, displayedComponents: .hourAndMinute)
DatePicker("To", selection: self.$scheduleController.timers[scheduleIndex].end, displayedComponents: .hourAndMinute)
Toggle(isOn: self.$scheduleController.timers[scheduleIndex].isActive) {
Text("")
}.toggleStyle(DefaultToggleStyle())
}
}
}
class ScheduleController: ObservableObject {
@Published var timers = [ScheduleTimer]()
...
Xcode 11, beta 6 UPDATE:
Good news! Just as I suspected, in beta 6, the Binding
conformance to MutableCollection
has been been replaced with something else. Instead of conforming to MutableCollection, it now let your access the elements via @dynamicMemberLookup
. The result is you now can keep doing $text[3]
and no longer get a warning! It seems this question can be closed now.
Xcode 11, beta 5. Old answer:
I finally got some time to investigate this a little. As I mentioned in the comments, I think it would be wise to wait until the Collection
conformance is completely removed (or replaced with something else). But just to satisfy our curiosity, I have created an extension on Binding
, that I think does what the current Collection
conformance does. The only difference is that, instead of accessing through a subscript, I implemented a function called element(_ idx: Int)
to get a Binding<T>
to the element.
If one day the conformance is completely removed, I may change the implementation, and conform to Collection
myself. I cannot do it now, because it would conflict with the existent (and deprecated) implementation. For the time being, I think this demonstrate how to handle the warnings if you absolutely want to get rid of them.
Just to be clear. I am not using this code. As long as I can still access the elements through the subscript, I will still do it and ignore the warnings. This is just for academic purposes.
The extension is:
extension Binding where Value: MutableCollection, Value.Index == Int {
func element(_ idx: Int) -> Binding<Value.Element> {
return Binding<Value.Element>(
get: {
return self.wrappedValue[idx]
}, set: { (value: Value.Element) -> () in
self.wrappedValue[idx] = value
})
}
}
And it can be used like this:
struct MainView: View {
@Binding var text: [String]
var body: some View {
TextField("", text: $text.element(0))
TextField("", text: $text.element(1))
TextField("", text: $text.element(2))
}
}