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?