是否可以使用拖放对 SwiftUI 表中的列重新排序?
Apple 于 2021 年夏季在 SwiftUI 3.0 中引入了“Table”。它相当于 NSTableView 的 SwiftUI。 我在苹果文档中找不到有关列重新排序的任何提示。
我说的是重新排序,正如我们从 NSTableViews 中知道的那样,就像 Finder 中的那样。
我使用了Apple提供的示例代码。
struct Person: Identifiable {
let givenName: String
let familyName: String
let id = UUID()
}
@State private var people = [
Person(givenName: "Juan", familyName: "Chavez"),
Person(givenName: "Mei", familyName: "Chen"),
Person(givenName: "Tom", familyName: "Clark"),
Person(givenName: "Gita", familyName: "Kumar"),
]
var body: some View {
Table(people, selection: $selectedPeople, sortOrder: $sortOrder) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
}
}
我还尝试为每个动态构建表列。但这会引发一堆调试错误。
@State private var columns = [
TableColumn("Given Name", value: \Person.givenName),
TableColumn("Family Name", value: \Person.familyName)
]
var body: some View {
Table(people, selection: $selectedPeople, sortOrder: $sortOrder) {
ForEach (columns, id: \.self) { column in
column
}
}
}
似乎 ForEach 与 TableColumns 不兼容:
通用结构“Table”要求“ForEach<[TableColumn
]、TableColumn 、某些 AccessibilityRotorContent>”符合“TableColumnContent”
静态方法“buildBlock”要求“ForEach<[TableColumn
]、TableColumn 、某些 AccessibilityRotorContent>”符合“TableColumnContent”
首先,你应该知道UITableView只有一列。 因此,为了帮助您解决问题,我建议您执行以下步骤。
要拥有多列的tableView,请创建多个UITableView,并将它们放在UI上。 (每个 tableView 将作为一列播放!) 现在您有一些彼此相邻的桌子,每张桌子都将作为一列进行游戏。
现在的问题是每个桌子都有自己的滚动条。 由于 UITableview 派生自 UIScrollview,您可以在“scrollViewDidScroll”委托方法中获取滚动量。 在此委托方法中,获取正在滚动的scrollView的偏移量,并将该值分配给其他tableView。
firstTableview.contentOffset = scrollview.contentOffset
现在所有 tableView 都将以相同的 px 高度同时滚动,感觉它们就像具有多个列的单个 TableView 一样。
最后,您希望用户能够对表格列重新排序(实际上您必须使 tableView 能够更改其位置) 为了实现这一点,你必须创建一个 UICollectionView,collectionView 的每个单元格都将是你的 tableView 之一。然后使用一些像“Reorder”这样的包来使单元格重新排序。 (重新排序GitHub地址:https://github.com/pikachu987/Reorder)
总结:
现在您有一个包含一些列的表,并且可以对列进行重新排序。
在 macOS 14 中,他们添加了一种简单的方法,通过
TableColumnCustomization
-> Apple 的文档文章。
示例:
struct BugReportTable: View {
@ObservedObject var dataModel: DataModel
@Binding var selectedBugReports: Set<BugReport.ID>
@SceneStorage("BugReportTableConfig")
private var columnCustomization: TableColumnCustomization<BugReport>
var body: some View {
Table(dataModel.bugReports, selection: $selectedBugReports,
sortOrder: $dataModel.sortOrder,
columnCustomization: $columnCustomization
) {
TableColumn("Title", value: \.title)
.customizationID("title")
TableColumn("ID", value: \.id) {
Link("\($0.id)", destination: $0.url)
}
.customizationID("id")
TableColumn("Number of Reports", value: \.duplicateCount) {
Text($0.duplicateCount, format: .number)
}
.customizationID("duplicates")
}
}
}