In my app I’ve got a list view and a view for displaying the rows in the list. When I delete an item from that list the app crashes in the row view stating an illegal access.
I don’t understand why the row view is rendered again for the deleted item.
The list view:
import Foundation
import SwiftUI
struct SpanList: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [ NSSortDescriptor(keyPath: \Span.startDate,
ascending: true) ],
predicate: NSPredicate(format: "isArchived != YES"),
animation: .default)
private var activeSpans: FetchedResults<Span>
var body: some View {
NavigationView {
VStack {
List {
Section(header: ActiveSectionHeader()) {
ForEach(activeSpans, id: \.id) { item in
NavigationLink(destination: getConfiguredEditView(span: item)) {
SpanRow(span: item)
}
.buttonStyle(PlainButtonStyle())
.listRowBackground(item.color.opacity(0.5))
}
.onDelete(perform: deleteItems)
}
}
.listStyle(GroupedListStyle())
}
}
}
private func getConfiguredEditView(span: Span) -> some View {
EditSpan(span: span)
.navigationTitle("Edit Span")
.navigationBarTitleDisplayMode(.inline)
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
// Necessary due to a bug in the framework. Without this the app crashes
// with a bug stating multiple access from different threads is not
// allowed.
viewContext.perform {
offsets.map {
activeSpans[$0]
}.forEach(viewContext.delete)
PersistenceController.shared.save()
}
}
}
}
The row view:
import SwiftUI
import CoreData
struct SpanRow: View {
@ObservedObject var span: Span
var body: some View {
HStack(alignment: .center) {
VStack(alignment: .leading) {
HStack {
if span.showOnStartPage && !span.isArchived {
Image(systemName: "paperclip")
}
Text(span.descriptionString)
.font(.headline)
.fontWeight(.bold)
}
Spacer()
HStack {
// It crashes here
Text("\(span.startDate, formatter: dateFormatter)")
Text("–")
if span.usesEndDate {
Text("\(span.endDate, formatter: dateFormatter)")
} else {
Image(systemName: "infinity")
}
}
}
Spacer()
if let daysSinceStart = span.daysSinceStart {
VStack {
Text("\(daysSinceStart)")
.font(.largeTitle)
.fontWeight(.semibold)
Text("days")
}
}
}
.padding(.vertical, 5)
}
private let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
return formatter
}()
}
What am I missing?