I have a NavigationSplitView where I list items in data storage. If I delete the selected one (the one that is showing details in the "detail" part of the navigationsplitview, the app crashes. If I delete one that is not selected at the moment, there is no crash. For the deletion I use the .onDelete event in the List inside the NavigationSplitView.
var body: some View {
@Bindable var nc = navigationContext
NavigationSplitView {
// let _ = print("Starting NavigationSplitView")
List(selection: $nc.selectedTimeline) {
// let _ = print("Starting List")
ForEach(timelines){ timeline in
NavigationLink(timeline.name, value: timeline)
}
.onDelete(perform: removeTimelines)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: {showNewTimeline = true}) {
Label("Add Timeline", systemImage: "plus")
}
}
ToolbarItem {
Button(action: {showEditTimeline = true}) {
Label("Edit Timeline", systemImage: "pencil")
}
}
}
} detail: {
TimelineView(timeline: nc.selectedTimeline)
.environment(navigationContext)
}
.sheet(isPresented: $showNewTimeline) {
TimelineEditorView(timeline: nil)
}
.sheet(isPresented: $showEditTimeline) {
TimelineEditorView(timeline: navigationContext.selectedTimeline)
}
}
func removeTimelines(at indexSet: IndexSet) {
print("Deleting timelines...")
for index in indexSet {
let timelineToDelete = timelines[index]
if navigationContext.selectedTimeline?.persistentModelID == timelineToDelete.persistentModelID {
navigationContext.selectedTimeline = nil
}
modelContext.delete(timelineToDelete)
}
}
The error is this: *** Assertion failure in -[SwiftUI.UpdateCoalescingCollectionView validateSelectionOrHighlightIndexPath:isSelection:allowMassIndexPath:assertIfInvalid:], UICollectionView.m:8266 Attempted to modify the selection of an out-of-bounds item (1) when there are only 1 items in section 0. Collection view: <SwiftUI.UpdateCoalescingCollectionView: 0x13480e600; baseClass = UICollectionView; frame = (0 0; 420 998); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x600001898390>; backgroundColor = UIExtendedGrayColorSpace 0 0; layer = <CALayer: 0x6000016949c0>; contentOffset: {0, -70}; contentSize: {420, 54}; adjustedContentInset: {70, 0, 0, 0}; layout: <UICollectionViewCompositionalLayout: 0x133e15090>; dataSource: <TtGC7SwiftUI31UICollectionViewListCoordinatorGVS_28CollectionViewListDataSourceC12Timeline_iOS8Timeline_GOS_19SelectionManagerBoxS3_: 0x135870160>>.
You are trying to deselect an item that no longer exists, causing the crash.
Change your removeTimelines
function to
func removeTimelines(at indexSet: IndexSet) {
print("Deleting timelines...")
for index in indexSet {
let timelineToDelete = timelines[index]
modelContext.delete(timelineToDelete)
}
}