NavigationSplitView list selection buggy after deleting?

I'm starting with the template code from Apple from: File > New Project > macOS app using Swift UI and Swift Data. Selection works fine if only adding items, but after deleting any selected item selection stops working for some rows. It seems like the UI and model get out of sync. After restarting the app, or simply launching a new window, it works again. Is this a known bug in Swift UI and is there a workaround?

import SwiftUI
import SwiftData

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var items: [Item]

    var body: some View {
        NavigationSplitView {
            List {
                ForEach(items) { item in
                    NavigationLink {
                        Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
                    } label: {
                        Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .navigationSplitViewColumnWidth(min: 180, ideal: 200)
            .toolbar {
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
        } detail: {
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(timestamp: Date())
            modelContext.insert(newItem)
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            for index in offsets {
                modelContext.delete(items[index])
            }
        }
    }
}

This seems to deal with a similar issue. Hope that can help:

https://www.hackingwithswift.com/forums/books/hacking-with-swiftdata-delete-a-sight/24119

Did you try to save the context to see if that solves ?

Thank you for your reply @Claude31!

Saving the context did unfortunately not help. Interestingly I could recreate the same issue using plain Swift structs as models instead of SwiftData, so it seems to be related to SwiftUI rather than SwiftData.

The link that you provided led me to another Apple sample project in which I was able to find a solution:

  • Provide the list with a selection, and
  • Use NavigationLink with value and move detail to the NavigationSplitView

I'm including these changes below in case anyone else runs into the same issue:

import SwiftUI
import SwiftData

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var items: [Item]
    @State private var selection: Item?

    var body: some View {
        NavigationSplitView {
            List(selection: $selection) {
                ForEach(items) { item in
                    NavigationLink(value: item) {
                        Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
                    }
                }
                .onDelete(perform: deleteItems)
            }
            .navigationSplitViewColumnWidth(min: 180, ideal: 200)
            .toolbar {
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
        } detail: {
            if let item = selection {
                Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
            } else {
                Text("Select an item")
            }
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(timestamp: Date())
            modelContext.insert(newItem)
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            for index in offsets {
                modelContext.delete(items[index])
            }
        }
    }
}
NavigationSplitView list selection buggy after deleting?
 
 
Q