Section 可以将视图在逻辑上分隔开,通常用于容器中,比如 Stack、List、Form 等。Section 不提供额外的视觉效果,但是可以添加自定义的 header 和 footer 视图。
比如用 Section 可以实现以下的效果,其中每个颜色是一个 Section:
首先定义一个结构 ColorData,用于存储每个 Section 的数据:
struct ColorData: Identifiable {
let id = UUID()
let name: String
let color: Color
let variations: [ShadeData]
struct ShadeData: Identifiable {
let id = UUID()
var brightness: Double
}
init(color: Color, name: String) {
self.name = name
self.color = color
self.variations = stride(from: 0.0, to: 0.5, by: 0.1)
.map { ShadeData(brightness: $0) }
}
}
然后定义一个 SectionHeaderView 显示在每个 Section 的上方:
struct SectionHeaderView: View {
var colorData: ColorData
var body: some View {
HStack {
Text(colorData.name)
.font(.headline)
.foregroundColor(colorData.color)
Spacer()
}
.padding()
.background(Color.primary
.colorInvert()
.opacity(0.75))
}
}
最后定义若干 ColorData,显示在 LazyVStack 和 ScrollView 中:
struct ColorSelectionView: View {
let sections = [
ColorData(color: .red, name: "Reds"),
ColorData(color: .green, name: "Greens"),
ColorData(color: .blue, name: "Blues"),
ColorData(color: .pink, name: "Pinks"),
ColorData(color: .yellow, name: "Yellows"),
ColorData(color: .orange, name: "Oranges"),
ColorData(color: .purple, name: "Purples"),
ColorData(color: .gray, name: "Grays")
]
var body: some View {
ScrollView {
LazyVStack(spacing: 1) {
ForEach(sections) { section in
Section(header: SectionHeaderView(colorData: section)) {
ForEach(section.variations) { variation in
section.color
.brightness(variation.brightness)
.frame(height: 20)
}
}
}
}
}
}
}
实现效果如下:
默认情况下 Section 的 header 会随着内容一起滚动,如果需要固定 header,可以在容器中指定固定 header 到顶部。
LazyVStack(spacing: 1, pinnedViews: [.sectionHeaders]) {
// ...
}
实现效果如下: