user11960918
user11960918

Reputation:

SwiftUI ForEach with .indices() does not update after onDelete

my problem is: I have simple array with some Items. I want to display a List with these items using a ForEach with .indices(). (This is because my actual problem handles with Toggle in a List and for the isOn binding I need the index to address a model that is bound to an EnvironmentObject). So the solution to loop over the array items is no possible solution for my problem.

The simplified starting point looks like this:

struct ContentView: View {
    @State var items = ["Item1", "Item2", "Item3"]
    
    var body: some View {
        List {
            ForEach(items.indices) {index in
                Text(self.items[index])
            }.onDelete(perform: deleteItem)
        }
    }
    
    func deleteItem(indexSet: IndexSet) {
        self.items.remove(atOffsets: indexSet)
    }
}

If I now try to swipe-delete a row, I get this error message:

Thread 1: Fatal error: Index out of range

Debugging the index value inside the closure, I can see, that the indices of the items-array does not update. For example: If I delete the first row with "Item 1" and inspect the value of index after deleting the row it returns 2 instead of 0 (which is the expected first index of the array). Why is this and how can I fix this problem?

Thanks for your help!

Upvotes: 7

Views: 3041

Answers (1)

Asperi
Asperi

Reputation: 257663

Just use dynamic content ForEach constructor (_ data: .., id: ...)

ForEach(items.indices, id: \.self) {index in   // << here !!
    Text(self.items[index])
}.onDelete(perform: deleteItem)

Upvotes: 6

Related Questions