I have a checklist made with LazyVStack, I implemented remove functionality for the checklist items, but for some reason the app crashes with "Index out of range" only when I try to remove the last element
Here is my code:
struct ChecklistView: View {
// Properties
// ==========
@ObservedObject var checklist = Checklist()
@ObservedObject var viewModel: ChecklistViewModel
@Binding var checklistItems: [ChecklistItem]
@State var newItemName = ""
@State var newChecklistItemViewIsVisible = false
@State var presentAddNewItem = true
let offlineMode: Bool
var body: some View {
VStack {
LazyVStack {
ForEach(checklistItems) { item in
HStack {
RowView(checklistItem: $checklistItems[item], viewModel: viewModel)
.listRowInsets(.init(top: 0, leading: 8, bottom: 0, trailing: 0))
.padding(.horizontal, 12)
.padding(.top, 12)
.padding(.bottom, 4)
Button {
//Prints the correct index number for the last element in the array, but when I remove the last element, always crashes.
print(index)
if let index = checklistItems.firstIndex(where: {$0.id == checklistItems[item].id}){
checklistItems.remove(at: index)
}
} label: {
Text("X")
}
}
Divider()
.frame(width: 311)
}
}
}
.frame(width: UIScreen.main.bounds.width - 32)
.background(backgroundSecondary)
.cornerRadius(16)
.overlay(
RoundedRectangle(cornerRadius: 16)
.stroke(borderGray, lineWidth: 1)
)
}
}
I found a solution, I changed my forEach to:
ForEach(checklistItems.indices, id: \.self) { index in
HStack {
RowView(
checklistItem:
Binding(
get: { self.checklistItems[index] },
set: { self.checklistItems[index] = $0 }
),
viewModel: viewModel
)
.padding(.leading, 12)
if checklistEditMode {
Button {
checklistItems.remove(at: index)
} label: {
Image("XCircle")
.resizable()
.frame(width: 18, height: 18)
}
.padding(.trailing, 12)
}
}
.padding(.horizontal, 12)
.padding(.top, 12)
.padding(.bottom, 4)
Divider()
.frame(width: 311)
}
and it works now with no crashes, Thanks to this