简体   繁体   中英

SwiftUI: How to create LazyGrid with equal number of rows and columns?

I am trying to create a grid in SwiftUI 2 using the new primitives LazyVGrid / LazyHGrid .

My goal is to create a grid with the following properties:

  • Each cell has the same width as height (basically a square)
  • The grid has an equal number of rows and columns (Columns = Rows)
  • The content should not be scrollable and always fit the size of my view/screen.

Here's a video with the expected results. This was achieved by a custom Grid object that uses GeometryReader .

在此处输入图像描述

I've tried using .contentMode(1, .fit) to restrain the LazyVGrid to a 1:1 ratio but it doesn't seem to work. The red background represents the frame of the Grid which is not the expected behaviour.

LazyVGrid(columns: [GridItem(.adaptive(minimum: 32), spacing: 0)], spacing: 0) {
    ForEach(1...100, id: \.self) { item in
        Rectangle()
            .aspectRatio(1, contentMode: .fit)
            .border(Color.black)
    }
}
.aspectRatio(1, contentMode: .fit)
.background(Color.red)

网格尝试

I have also tried using GeometryReader to fix the size of the LazyVGrid , but it still didn't work. Any other ideas on how to achieve this?

Try the following (tested with Xcode 12b3 / iOS 14, no big-sur)

struct TestGridFitView: View {
    let columns = Array(repeating: GridItem(.flexible(minimum: 32), spacing: 0), count: 10)
    var body: some View {
        LazyVGrid(columns: columns, spacing: 0) {
            ForEach(1...100, id: \.self) { item in
                Rectangle().fill(Color.clear)
                    .aspectRatio(1, contentMode: .fit)
                    .border(Color.black)
            }
        }
        .background(Color.red)
        .aspectRatio(contentMode: .fit)
        
    }
}

backup

After seeing @Asperi 's solution above, I've managed to solve the final piece of the puzzle. Here's the code:

var body: some View {
    let columns = Array(repeating: GridItem(.flexible(minimum: 4, maximum: 48), spacing: 0), count: 10)

    LazyVGrid(columns: columns, spacing: 0) {
        ForEach(1...100, id: \.self) { item in
            Rectangle()
                .aspectRatio(1, contentMode: .fit)
                .border(Color.black)
        }
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
    .aspectRatio(1, contentMode: .fit)
    .background(Color.red)
}

完成品

Have you tried giving an infinity max width? Like this:

    LazyVGrid(columns: [GridItem(.adaptive(minimum: 32), spacing: 0)], spacing: 0) {
    ForEach(1...100, id: \.self) { item in
        Rectangle()
            .aspectRatio(1, contentMode: .fit)
            .border(Color.black)
    }
}
.frame(maxWidth: .infinity)
.background(Color.red)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM