SwiftUI dynamic List with Sections does not Layout correctly

Bo Frese picture Bo Frese · Jun 20, 2019 · Viewed 10.1k times · Source

I'm trying to create a simple dynamic list grouped into sections. (SwiftUI iOS13 Xcode11 beta 2)

A simple static example would be :

struct StaticListView : View {
    var body: some View {
        List {
            Section(header: Text("Numbers"), footer: Text("...footer...")) {
                Text("1")
                Text("2")
                Text("3")
            }
            Section(header: Text("Letters"), footer: Text("...footer...")) {
                Text("a")
                Text("b")
                Text("c")
            }
        }
    }
}

This displays as expected a nice list with section headers and footers

But when I try to do this from a dynamic list like this :

struct TestData: Identifiable {
    var id = UUID()
    var title: String
    var items: [String]
}

struct ListView : View {
    let mygroups = [
        TestData(title: "Numbers", items: ["1","2","3"]),
        TestData(title: "Letters", items: ["A","B","C"]),
        TestData(title: "Symbols", items: ["€","%","&"])
    ]
    var body: some View {
        List (mygroups) { gr in
            Section(header: Text(gr.title),
                    footer: Text("...footer...") ) {
                ForEach(gr.items.identified(by: \.self)) { item in
                    Text(item)
                }
            }
        }
    }
}

The result is a list with only 3 rows. Both the Section header, all the content cells and the footer are combined horizontally into a single row.

What am I missing?

Answer

piebie picture piebie · Jun 20, 2019

Giving List a set of items seems to make it incorrectly treat Section as a single view.

You should probably file a radar for this, but in the meantime, this will give you the behavior you're looking for:

struct ListView : View {
    let mygroups = [
        TestData(title: "Numbers", items: ["1","2","3"]),
        TestData(title: "Letters", items: ["A","B","C"]),
        TestData(title: "Symbols", items: ["€","%","&"])
    ]

    var body: some View {
        List {
            ForEach(mygroups) { gr in
                Section(header: Text(gr.title),
                        footer: Text("...footer...") ) {
                            ForEach(gr.items.identified(by: \.self)) { item in
                                Text(item)
                            }
                }
            }
        }
    }
}