使用 LazyVGrid 对齐字幕和页脚?

Align Subtitles and Footers with LazyVGrid?

我对使用 LazyVGrid 对齐每列的字幕和页脚有疑问。假设我有这样的观点:

 Title


 Subtitle A     Subtitle B     Subtitle C

   row1A          row1B          row1C
   row2A          row2B          row2C
   row3A          row3B          row3C
   row4A          row4B          row4C
   row5A          row5B          row5C

  Total A        Total B        Total C

目前我使用 Geometry Reader 来显示 header 和页脚,并使用 LazyVGrid 来显示数据。我注意到,如果我将字幕与 12 ProMax 模拟器对齐,然后在 12 Mini 模拟器上查看我的设置,Mini 字幕已经移动并且看起来不是很专业。是否可以在 LazyVGrid 中使用类似下面的内容来不仅显示数据,还显示字幕和页脚?使用 pinnedViews: [] 我可以显示第一列 header,但如何显示所有三个字幕和页脚?有一些 Apple 文档 here 关于使用节 headers 但没有关于多节 headers 和页脚的内容。

private var columns: [GridItem] = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible())
    ]
    var body: some View {

    GeometryReader { g in
        ScrollView {
            VStack (alignment: .leading) {

   ShowTitle()

   ShowSubTitle()

       LazyVGrid(
           columns: columns,
           alignment: .leading,
           spacing: 10,  // vertical spacing
           pinnedViews: [.sectionHeaders, .sectionFooters]
       ) {

           Section(header: Text("Subtitle A")
                 .font(.headline)) {
               ForEach(0..<self.categories.catItem.count, id: \.self) { index in
                  ShowRow(index: index)
                }
             }
          }

我从 Grouping Data with Lazy Stack Views 的 Apple 示例中模拟了这个。诀窍是将 LazyVStack 放在 ForEach 内,像这样遍历每个部分:

struct LazyVGridSectioned: View {
    let sections = [
        ColorData(color: .red, name: "Reds", footerInfo: "Red Footer Info"),
        ColorData(color: .green, name: "Greens", footerInfo: "Green Footer Info"),
        ColorData(color: .blue, name: "Blues", footerInfo: "Blue Footer Info")
    ]
    
    var body: some View {
        ScrollView {
            HStack {
                ForEach(sections) { section in
                    LazyVStack(spacing: 1, pinnedViews: [.sectionHeaders, .sectionFooters]) {
                        Section(header: SectionHeaderView(colorData: section), footer: SectionFooterView(colorData: section)) {
                            ForEach(section.variations) { variation in
                                section.color
                                    .brightness(variation.brightness)
                                    .frame(height: 20)
                            }
                        }
                    }
                }
            }
        }
    }
}
    

struct SectionHeaderView: View {
    var colorData: ColorData

    var body: some View {
        HStack {
            Spacer()
            Text("Header for \(colorData.name)")
                .font(.headline)
                .foregroundColor(colorData.color)
            Spacer()
        }
        .padding()
        .background(Color.primary
                        .colorInvert()
                        .opacity(0.75))
    }
}

struct SectionFooterView: View {
    var colorData: ColorData

    var body: some View {
        HStack {
            Spacer()
            Text(colorData.footerInfo)
                .font(.headline)
                .foregroundColor(colorData.color)
            Spacer()
        }
        .padding()
        .background(Color.primary
                        .colorInvert()
                        .opacity(0.75))
    }
}
    

struct ColorData: Identifiable {
    let id = UUID()
    let name: String
    let footerInfo: String // Add parameter in ColorData
    let color: Color
    let variations: [ShadeData]

    struct ShadeData: Identifiable {
        let id = UUID()
        var brightness: Double
    }

    // Add it to the init as well
    init(color: Color, name: String, footerInfo: String) {
        self.name = name
        self.color = color
        self.footerInfo = footerInfo // Assign it here
        self.variations = stride(from: 0.0, to: 0.5, by: 0.1)
            .map { ShadeData(brightness: [=10=]) }
    }
}