SwiftUI dynamic List with Sections does not Layout correctly
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)
}
}
}
}
}
}
Just a small fix for a correct answer above. Since
ForEach(gr.items.identified(by: \.self)) { item in
Text(item)
}
does not compile as for me, so this do compile and works like a charm:
ForEach(gr.items, id: \.self, content: { item in
Text(item)
})
While the above solutions work for static data, I'm running into a different situation. In my case, the "mygroups" equivalent is empty when the List is first composed. In the .onAppear{} block, I build the groups.
Once the groups are built I update the @State and the List crashes with this old friend message:
'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (2) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (2 inserted, 0 deleted).'
I went from an empty array to one with two sections. I don't think the List is ready yet for such complex dynamic changes (unless there's an API I haven't found yet).
What I'm likely to do is try and build this before the List gets a chance to see it.