How to build square cells in a SwiftUI LazyVGrid containing dynamic type

469 Views Asked by At

I'm trying to build a LazyVGrid, that contains square cells that dynamically size with the text inside them, something like this:

struct BandView: View {
    
    let bands: [Band]
    
    var body: some View {
        LazyVGrid(columns: [GridItem(.adaptive(minimum: 120))]) {
            ForEach(bands, id: \.self) { band in
                BandCell(band: band)
            }
        }
        .frame(maxHeight: .infinity, alignment: .topLeading)
        .padding()
    }
}

struct BandCell: View {
    
    let band: Band
    
    var body: some View {
        GroupBox {
            VStack(alignment: .leading, spacing: 8) {
                Text(band.leadSinger)
                    .lineLimit(1)
                Text("\(band.songs) songs")
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
        } label: {
                Text(band.name)
                    .lineLimit(2)
        }
        .aspectRatio(1, contentMode: .fill)
    }
}

struct BandView_Previews: PreviewProvider {
    
    static var bands = [
        Band(name: "Wet Leg", leadSinger: "Rhian Teasdale", songs: 2),
        Band(name: "The Cure", leadSinger: "Robert Smith", songs: 6),
        Band(name: "Dave Dee, Dozy, Beaky, Mick & Tich ", leadSinger: "Dave Dee", songs: 5)
    ]
    
    static var previews: some View {
        BandView(bands: bands)
    }
}


struct Band: Hashable {
    let name: String
    let leadSinger: String
    let songs: Int
}

which gives me the following when using a large dynamic type size:

enter image description here

However, when I increase the font size to accessibility 3 or more the cells take up more space so that they overlap the frame of the grid (and each other):

enter image description here

I was expecting the cells to grow, but as I'm using GridItem(.adaptive) I assumed they would move onto separate rows.

Changing the aspect ratio to fit rather than fill, i.e.

.aspectRatio(1, contentMode: .fit)

and the cells stretch vertically, so don't keep the aspect ratio.

enter image description here

What am I missing?

0

There are 0 best solutions below