如何获取macOS上SwiftUI Table的单击(列、行)信息?
macOS SwiftUI Table 获取点击的行列信息
直接给Table添加onTapGesture不会触发,是因为Table内部的单元格自带更高优先级的手势识别,外层手势被拦截了。要获取点击的行列信息,可以给每个单元格单独添加手势处理,具体实现如下:
步骤1:定义列标识枚举
先创建一个枚举来标记不同的列,方便后续区分点击的是哪一列:
enum PersonColumn: String { case givenName, familyName, emailAddress }
步骤2:自定义单元格并添加点击手势
放弃自动绑定value的方式,改用TableColumn的闭包自定义单元格内容,给每个单元格添加onTapGesture,同时传递行数据和列标识:
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: "juanchavez@icloud.com"), Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com"), Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com"), Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com") ] // 处理单元格点击的方法 private func handleCellTap(person: Person, column: PersonColumn) { // 获取行索引(如果需要) let rowIndex = people.firstIndex(where: { $0.id == person.id }) ?? -1 print("点击了行:\(rowIndex),列:\(column.rawValue)") // 在这里更新视图模型的单元格选中状态 // 示例:viewModel.selectCell(rowID: person.id, column: column) } var body: some View { Table(people) { TableColumn("Given Name") { person in Text(person.givenName) .onTapGesture { handleCellTap(person: person, column: .givenName) } } TableColumn("Family Name") { person in Text(person.familyName) .onTapGesture { handleCellTap(person: person, column: .familyName) } } TableColumn("E-Mail Address") { person in Text(person.emailAddress) .onTapGesture { handleCellTap(person: person, column: .emailAddress) } } } } } #Preview { PeopleTable() }
扩展:实现视图模型的单元格选中
如果要在视图模型中管理选中状态,可以在视图模型里定义一个存储选中单元格的集合,比如:
class PeopleViewModel: ObservableObject { @Published var people: [Person] = [...] @Published var selectedCells: Set<(rowID: UUID, column: PersonColumn)> = [] func selectCell(rowID: UUID, column: PersonColumn) { let key = (rowID: rowID, column: column) if selectedCells.contains(key) { selectedCells.remove(key) } else { selectedCells.insert(key) } } }
然后在PeopleTable中注入视图模型,在handleCellTap里调用viewModel.selectCell即可。
内容的提问来源于stack exchange,提问作者user2962393
相关产品推荐
相关产品推荐

