I'm developing a macOS App with a List View with selectable rows.
As there is unfortunately no editMode
on macOS, Single Click Selection of Cells is possible, but deselecting an already selected Cell doing the same does nothing.
The only option to deselect the Cell is to CMD Click which is not very intuitive.
Minimum Example:
struct RowsView: View {
@State var selectKeeper: String?
let rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
var body: some View {
List(rows, id: \.self, selection: $selectKeeper) { row in
Text(row)
}
}
}
struct RowsView_Previews: PreviewProvider {
static var previews: some View {
RowsView()
}
}
Clicking Row Nr 3 with a Single Click or even double Click does nothing and the row stays selected.

Attaching Binding directly
I have tried to attach the Binding directly as described in the excelent answer for a Picker 
struct RowsView: View {
@State var selectKeeper: String?
let rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
var body: some View {
List(rows, id: \.self, selection: $selectKeeper) { row in
Text(row)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.contentShape(Rectangle()) // handle click row-wide
.listRowInsets(EdgeInsets()) // remove default edges
.onTapGesture {
selectKeeper = selectKeeper == row ? nil : row // << here !!
}
.padding(.vertical, 4) // look&feel like default
}
}
}
CodePudding user response:
I refer to this answer to a SO post titled "Select Multiple Items in a SwiftUI List".
From this answer I generated code to select multiple items in a list.
In my sample code I use a checkmark to illustrate whether a row is selected, but you could change this to suit your needs.
You'll need to change your @State wrapper to a Set, because you confirmed that you'll need to select a group of items. (An aside, Apple advises that you mark @State property wrappers as private.)
@State private var selectedItems: Set<String>?
let rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
var body: some View {
List(rows, id: \.self) { item in
RowSelectable(selectedItems: $selectedItems, rowItem: item)
}
}
where RowSelectable is...
struct RowSelectable: View {
@Binding var selectedItems: Set<String>?
var rowItem: String
var isSelected: Bool {
return selectedItems?.contains(rowItem) == true
}
var body: some View {
HStack {
Text(rowItem.rowSheet)
if selectedItems?.contains(rowItem) == true {
Spacer()
Image(systemName: "checkmark")
}
}
.onTapGesture(count: 1) {
if self.isSelected {
selectedItems!.remove(rowItem)
}
else {
selectedItems!.insert(rowItem)
}
}
}
}
I haven't tested this yet, so let me know if it doesn't work and I'll check in Xcode.

