I have problems with deleting cells that contain a Toggle.
My model looks like this:
class Model: ObservableObject {
@Published var items: [Item]
init(items: [Item]) {
self.items = items
}
}
struct Item: Identifiable {
var id = UUID()
var text: String
var isImportant: Bool
}
And my views are these:
struct ContentView: View {
@EnvironmentObject var model: Model
var body: some View {
List {
ForEach(model.items) {item in
ItemCell(item: item).environmentObject(self.model)
}
.onDelete(perform: deleteItem)
}
}
func deleteItem(indexSet: IndexSet) {
indexSet.forEach({model.items.remove(at: $0)})
}
}
struct ItemCell: View {
@EnvironmentObject var model: Model
var item: Item
var itemIndex: Int {model.items.firstIndex(where: {$0.id == item.id})!}
var body: some View {
Toggle(isOn: $model.items[itemIndex].isImportant) {
Text(item.text)
}
}
}
As you can see I use @EnvironmentObject
. Every time I try to delete a cell, I get this error message shown in the AppDelegate
:
Thread 1: Fatal error: Index out of range
I assume the problem is how I pass the data from my ContentView()
to the ItemCell()
. I also tried to integrate the code of ItemCell()
into the closure of the ForEach
but this didn't work.
Hope someone can help me.
Additional question: What is the purpose of injection with EnvironmentObject (.environmentObject(self.model)
)? I don't understand when to use it and when not. In my understanding the EnvironmentObject is a global object that lives in the environment and has always updated information, independent on the View.
Thanks! Nico
UPDATE:
I had another idea, that didn't work either:
ContentView
:
ForEach(model.items.indices) {index in
ItemCell(item: self.$model.items[index]).environmentObject(self.model)
}
and ItemCell
:
@Binding var item: Item
var body: some View {
Toggle(isOn: $item.isImportant) {
Text(item.text)
}
}
Any ideas?
UPDATE 2
Also this didn't work:
ForEach(Array(model.items.enumerated()), id: \.element) {index, item in
ItemCell(item: self.$model.items[index]).environmentObject(self.model)
}