'HTML-like table layout (i.e. auto-resizing table cells) in SwiftUI View?

I’d like to render a table of text cells in my SwiftUI View in a way, that every cell auto-resizes just so much that the text fits in it. So I did this:

    import SwiftUI

    struct ContentView: View {

        let words = "Die Würde des Menschen ist unantastbar. Sie zu achten und zu schützen ist Verpflichtung aller staatlichen Gewalt.".split(separator: " ")

        let columns = [
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible()),
        ]

       var body: some View {
           HStack{
               Spacer()
               LazyVGrid(columns: columns, spacing: 10) {
                   ForEach(words.indices, id: \.self) { idx in
                       HStack{
                           Text(words[idx])
                           Spacer()
                       }
                   }
               }
               Spacer()
           }.padding().frame(width:600)
       }
    }

However, the columns render with a fixed width and a lot of whitespace. (I don’t understand "flexible" in this context.) I‘d like to see HTML-table-like behavior, i.e., the columns should not be wider than the widest element.



Solution 1:[1]

GridItem(.flexible()) gives all cells a flexible, but SAME width. Seems like you are looking for flexible widths. The easiest way would be to skip LazyVGrid and just use HStack and VStack, they size themselves variable based on their content:

    var body: some View {
        
        HStack {
            ForEach(0..<5) { col in
                VStack(alignment: .leading) {
                    ForEach(0..<4) { row in
                        let index = row*5 + col
                        if index < words.count {
                            Text(words[index])
                        } else {
                            Text("")
                        }
                    }
                }
            }
        }
        .padding()
        .frame(width:600)
    }

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ChrisR