When user single-clicks a SwiftUI Table on macOS, I'd like to know the clicked (column, row) pair, or point. I added onTapGesture() handler to the Table, but it's never invoked. How can I figure out which (column, row) was clicked?
My goal is to implement cell selection in my view model. I need to be able to determine the clicked (column, row) pair in order to select the correct cell in the view model.
Below is Apple example code, to which I added the ineffective onTapGesture() handler.
struct Person: Identifiable {
let givenName: String
let familyName: String
let emailAddress: String
let id = UUID()
}
struct PeopleTable: View {
@State private var people = [
Person(givenName: "Juan", familyName: "Chavez", emailAddress: "Answer
Pass a View to the TableColumns, and add the tap gesture to that.
Table(people) {
TableColumn("Given Name") { person in
Text(person.givenName)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.contentShape(.rect)
.onTapGesture {
print("Clicked given name of \(person.id)")
}
}
TableColumn("Family Name") { person in
Text(person.familyName)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.contentShape(.rect)
.onTapGesture {
print("Clicked family name of \(person.id)")
}
}
TableColumn("E-Mail Address") { person in
Text(person.emailAddress)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.contentShape(.rect)
.onTapGesture {
print("Clicked email address of \(person.id)")
}
}
}
I have used frame and contentShape to increase the tappable as much as possible. Without those, the empty parts of the table cells are not tappable.
If this is still unsatisfactory, I would recommend wrapping a NSTableView with a NSViewRepresentable. You would set its action to a method, then access clickedColumn and clickedRow in that method.

