macOS App中SwiftUI如何处理选中行的双击事件?
macOS SwiftUI Table 选中行双击事件处理方案
推荐方案(macOS 13+)
直接利用SwiftUI Table提供的.onRowGesture修饰符,统一给所有行添加双击手势,同时在回调中判断当前行是否处于选中状态,无需在每列重复编写手势代码。
修改后的代码示例:
Table(transactions, selection: $selectedTransactions) { TableColumn("Date") { transaction in Text(transaction.transactionDate, formatter: dateFormatter) .foregroundColor(transaction.transactionStatus.statusColor) } // 其他列正常定义即可,不用加手势 } .onRowGesture(TapGesture(count: 2)) { transaction in // 检查当前双击的行是否在选中集合内 if selectedTransactions.contains(transaction) { print("双击了选中的行") // 在这里添加你的业务处理逻辑,比如打开详情页 } }
兼容旧版本方案(macOS 12及以下)
如果需要兼容更早的系统版本,可以通过桥接AppKit的NSTableView来实现:
struct ContentView: View { @State var transactions: [Transaction] = [] @State var selectedTransactions: Set<Transaction> = [] private let dateFormatter = DateFormatter() var body: some View { Table(transactions, selection: $selectedTransactions) { TableColumn("Date") { transaction in Text(transaction.transactionDate, formatter: dateFormatter) .foregroundColor(transaction.transactionStatus.statusColor) } } .onAppear { // 获取底层的NSTableView实例 if let tableView = NSApp.keyWindow?.contentView?.subviews.first(where: { $0 is NSTableView }) as? NSTableView { tableView.doubleAction = #selector(tableViewDoubleClick(_:)) tableView.target = self } } } @objc private func tableViewDoubleClick(_ sender: NSTableView) { let clickedRow = sender.clickedRow // 安全获取点击行的数据,并检查是否选中 guard clickedRow != -1, let transaction = transactions[safe: clickedRow], selectedTransactions.contains(transaction) else { return } print("双击了选中的行") // 添加你的处理逻辑 } } // 给数组添加安全下标扩展,避免越界 extension Collection { subscript(safe index: Index) -> Element? { indices.contains(index) ? self[index] : nil } }
说明
- 推荐方案完全遵循SwiftUI声明式风格,代码简洁易维护,是首选方案。
- 旧版本方案需要依赖AppKit的API,适合必须兼容macOS 12及以下的项目。
内容的提问来源于stack exchange,提问作者Sébastien REMY
相关产品推荐
相关产品推荐

