There are a couple of questions in here.
I want to do a basic master-detail split view, as so many SwiftUI apps do. But I want to let the user select an arbitrary subset of items in the list, select them all, and delete them (or do other operations).
- Select All, by default, is excruciatingly slow. I have a List view with a selection binding to a
Set<PersistentIdentifier>
. A ForEach inside renders the items from a SwiftData@Query
. I have a couple hundred items, each with a String and Date property. The list item renders the String and nothing else.
I click on an item, hit Command-A, and the app locks up for several seconds while it messes with the selection. It never highlights all the items, but sometimes highlights one (usually different from the one I clicked on).I have an .onChange(of: self.selection)
in there to debug the selection. It is called many, many times (2-3 times per second, very slowly), and print the selection count, which starts at 135, and goes down by one, to about 103. If I scroll the list, the selection onChange gets called a bunch more times. Sometimes you see the selection highlights change.
My SwiftUI view hierarchy looks like this:
NavigationSplitView OrdersList struct OrdersList : View { var body: some View { List(selection: self.$selection) { ForEach(self.orders) { order in NavigationLink { Text("Order ID: \(order.vendorOrderID ?? "<none>")") } label: { Text("Order ID: \(order.vendorOrderID ?? "<none>")") } } .onDelete(perform: self.deleteOrders) .onChange(of: self.selection) { print("Selection changed: \(self.selection.count)") } } } func deleteOrders(offsets: IndexSet) { withAnimation { for index in offsets { self.modelContext.delete(self.orders[index]) } } } @State var selection = Set<PersistentIdentifier>() @Query var orders : [Order] @Environment(\.modelContext) var modelContext }
- If I use the mouse to select a single item, it behaves as expected. The item is selected, the onChange gets called, and if I choose Edit->Delete, the onDelete handler is called.
If I use the mouse to shift-select multiple items, the behavior is similar to Select All above, but the selection Set count starts at the number of items I selected, and then is slowly whittled down to 0 or 1, with some random item being selected.
- I’d like for the Edit->Delete command to work with a keystroke (delete). How can I set the shortcut on an existing menu item without having to reimplement its behavior?