将带有 Header 的部分添加到带有可扩展行的 SwiftUI 列表

Adding Section with Header to SwiftUI List with Expandable Rows

我有一个包含 expandable/collapsable 行的 SwiftUI 列表。我正在尝试在列表顶部添加标题为 header 的部分。添加部分之前的代码如下:

var body: some View {
        List(parentArray, id: \.self, children: \.child) {  item in
                ResultsRowView(circle: item.circle.lowercased(), person: item.person, tally: item.tally)
        }.listStyle(GroupedListStyle())
    }

当我尝试添加一个部分时,我得到了奇怪的结果。例如,我试过这个:

var body: some View {
        List(parentArray, id: \.self, children: \.child) {  item in
            Section(header: Text("HeaderTitle")) {
                ResultsRowView(circle: item.circle.lowercased(), person: item. person, tally: item.tally)
            }
        }.listStyle(GroupedListStyle())
    }

但这只会向列表中的每一行添加一个“HeaderTitle”文本元素。

然后我试了这个:

var body: some View {
        Section(header: Text("HeaderTitle")) {
            List(parentArray, id: \.self, children: \.child) {  item in
                    ResultsRowView(circle: item.circle.lowercased(), person: item.person, tally: item.tally)
            }.listStyle(GroupedListStyle())
        }
    }

但这样做的结果是列表完全消失,取而代之的是设置在屏幕中间的文本“HeaderTitle”。

正如您可能想象的那样,我正在寻找的结果是列表顶部带有 header 的部分。有什么想法吗?

编辑:我自己的数据太麻烦了,无法包含给其他人试用。但下面的代码与我自己的结构相同,摘自 Paul Hudson 的 Hacking With Swift 网站:

import SwiftUI

struct ContentView: View {
    let items: [Bookmark] = [.example1, .example2, .example3]

    var body: some View {
        List(items, children: \.items) { row in
            Image(systemName: row.icon)
            Text(row.name)
                
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Bookmark: Identifiable {
    let id = UUID()
    let name: String
    let icon: String
    var items: [Bookmark]?

    // some example websites
    static let apple = Bookmark(name: "Apple", icon: "1.circle")
    static let bbc = Bookmark(name: "BBC", icon: "square.and.pencil")
    static let swift = Bookmark(name: "Swift", icon: "bolt.fill")
    static let twitter = Bookmark(name: "Twitter", icon: "mic")

    // some example groups
    static let example1 = Bookmark(name: "Favorites", icon: "star", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example2 = Bookmark(name: "Recent", icon: "timer", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
    static let example3 = Bookmark(name: "Recommended", icon: "hand.thumbsup", items: [Bookmark.apple, Bookmark.bbc, Bookmark.swift, Bookmark.twitter])
}

您可以将其包裹在一个表单中,使其成为 header:

var body: some View {
    Form {
        Section(header: Text("Header Text")) {
            List(items, children: \.items) { row in
                Image(systemName: row.icon)
                Text(row.name)
            }
        }
    }
}

如果您想要另一种样式,如果我找到在显示 header 时保持列表样式的任何方法,我会更新此答案。

struct ContentView: View {
    let items: [Bookmark] = [.example1, .example2, .example3]
    
    var body: some View {
        
        List {
            Section(header: Text("Heading")) {
                ForEach(items) { row in
                    HStack {
                        Image(systemName: row.icon)
                        Text(row.name)
                    }
                }
            }
        }.listStyle(GroupedListStyle())
    }
}

截图