I am trying to implement a table that follows system style on macOS. There seem to be two ways to do this:
struct MyRow: Identifiable {
let id = UUID()
var title: String
}
struct MySection: Identifiable {
let id = UUID()
var title: String
var rows: [MyRow]
}
-
Iterate via List:
List(sections) { section in Section(header: Text(section.title)) { ForEach(section.rows) { row in Text(row.title) } } }
This works and is stable, but does not apply any formatting. It seems to use stacks under the hood:
(can't include screenshot, restricted by forum)
-
Iterate via ForEach
List { ForEach(sections) { section in Section(header: Text(section.title)) { ForEach(section.rows) { row in Text(row.title) } } } }
This is exactly what I want. For some reason, this applies the system styles, has floating group rows etc. - all the things you would expect from a native NSTableView:
But here is the problem:
It crashes as soon as the order of sections/rows changes at a later point. I assume this is a SwiftUI Bug:
**Could not cast value of type 'SwiftUI.ListCoreCellHost' (0x7fff87be7580) to 'SwiftUI.ListCoreHeaderHost' (0x7fff87be75f8).**
**2020-07-05 11:52:00.779004-0700 SwiftUIRepro[47587:1158522] Could not cast value of type 'SwiftUI.ListCoreCellHost' (0x7fff87be7580) to 'SwiftUI.ListCoreHeaderHost' (0x7fff87be75f8).**
I created a repro to demonstrate the bug here: GitHub - paxos/SwiftUICrashRepro
Also, on macOS 11.16 this doesn't work at all; it just shows empty rows. I assume we are supposed to use the new outline views in the future?
I am bit stuck here. I could use approach 1) and just style everything by myself, but that is usually not what you want to do on macOS.
Any ideas? Am I doing something wrong here?