Table
是 SwiftUI 中用于展示多列数据的视图容器,特别适合 macOS 和 iPadOS 上的表格布局(类似于 UITableView
或 NSTableView
)。以下是 Table
的体系结构和使用方法的详细介绍:
1. Table 的体系结构 #
核心组件 #
Table
容器:用于定义表格的整体结构和列布局。TableColumn
:定义表格的列,包括标题、数据绑定和内容渲染。- 数据源:通过集合(如数组)提供表格的行数据,通常结合
Identifiable
协议确保每行有唯一标识。
关键特性 #
- 多列支持:支持动态列数和列排序。
- 行选择:支持单行或多行选择(通过
selection
绑定)。 - 排序:通过
sortComparator
实现列排序。 - 样式:支持自定义行高、列宽和单元格内容。
2. 基本使用方法 #
步骤 1:定义数据模型 #
确保数据模型遵循 Identifiable
协议,以便每行有唯一标识。
struct Person: Identifiable {
let id = UUID()
var name: String
var age: Int
var email: String
}
步骤 2:创建 Table #
使用 Table
容器定义表格,并通过 TableColumn
定义列。
struct ContentView: View {
@State private var people = [
Person(name: "Alice", age: 30, email: "alice@example.com"),
Person(name: "Bob", age: 25, email: "bob@example.com"),
Person(name: "Charlie", age: 35, email: "charlie@example.com")
]
var body: some View {
Table(people) {
TableColumn("Name", value: \.name)
TableColumn("Age", value: \.age)
TableColumn("Email", value: \.email)
}
}
}
3. 高级功能 #
(1) 自定义列内容 #
通过闭包自定义列的渲染逻辑。
TableColumn("Name") { person in
HStack {
Image(systemName: "person.circle")
Text(person.name)
}
}
(2) 行选择 #
通过 selection
绑定实现行选择(支持单行或多行)。
@State private var selectedPersonID: UUID?
Table(people, selection: $selectedPersonID) {
TableColumn("Name", value: \.name)
TableColumn("Age", value: \.age)
TableColumn("Email", value: \.email)
}
(3) 排序 #
通过 sortComparator
实现列排序。
@State private var sortOrder = [KeyPathComparator(\Person.name)]
Table(people, sortOrder: $sortOrder) {
TableColumn("Name", value: \.name)
TableColumn("Age", value: \.age)
TableColumn("Email", value: \.email)
}
.onChange(of: sortOrder) { newOrder in
people.sort(using: newOrder)
}
(4) 动态列 #
根据条件动态生成列。
@State private var showEmailColumn = true
Table(people) {
TableColumn("Name", value: \.name)
TableColumn("Age", value: \.age)
if showEmailColumn {
TableColumn("Email", value: \.email)
}
}
(5) 样式调整 #
通过 tableStyle
设置表格样式(如 .inset
、.bordered
)。
Table(people) {
TableColumn("Name", value: \.name)
TableColumn("Age", value: \.age)
TableColumn("Email", value: \.email)
}
.tableStyle(.inset)
4. 完整示例 #
以下是一个包含选择、排序和自定义列内容的完整示例:
struct ContentView: View {
@State private var people = [
Person(name: "Alice", age: 30, email: "alice@example.com"),
Person(name: "Bob", age: 25, email: "bob@example.com"),
Person(name: "Charlie", age: 35, email: "charlie@example.com")
]
@State private var selectedPersonID: UUID?
@State private var sortOrder = [KeyPathComparator(\Person.name)]
var body: some View {
VStack {
Table(people, selection: $selectedPersonID, sortOrder: $sortOrder) {
TableColumn("Name", value: \.name) { person in
HStack {
Image(systemName: "person.circle")
Text(person.name)
}
}
TableColumn("Age", value: \.age)
TableColumn("Email", value: \.email)
}
.onChange(of: sortOrder) { newOrder in
people.sort(using: newOrder)
}
.tableStyle(.inset)
if let selectedID = selectedPersonID, let person = people.first(where: { $0.id == selectedID }) {
Text("Selected: \(person.name)")
}
}
.padding()
}
}
5. 注意事项 #
- 平台支持
Table
主要用于 macOS 和 iPadOS,iOS 上通常使用List
或LazyVStack
替代。
- 性能优化
- 对于大数据集,确保数据模型轻量,避免复杂计算或渲染逻辑。
- 样式限制
Table
的样式定制能力有限,复杂需求可能需要自定义视图或结合 AppKit/UIKit。
6. 对比其他组件 #
组件 | 适用场景 | 特点 |
---|---|---|
Table | 多列数据展示(macOS/iPadOS) | 支持排序、选择、动态列,适合复杂表格。 |
List | 单列数据展示(全平台) | 简单易用,支持 Section 和动态内容。 |
LazyVStack | 自定义布局(全平台) | 灵活但需手动管理布局和性能优化。 |
通过 Table
,你可以快速构建功能丰富的表格视图,适用于数据密集型的 macOS 和 iPadOS 应用。