Search code examples
swiftuilazyvgrid

Center the last row in a LazyVGrid


In a LazyVGrid, I show data coming from the server (here I'm using the alphabet as an example), and my goal is to show the last row in a center instead of leading if the last row contains less than 3 items. Is it doable?

Currently, it looks like this:

enter image description here

struct ContentView: View {
   let alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    let preference = [
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible())
        ]
    var body: some View {
    ScrollView {
        LazyVGrid(columns: preference) {
        ForEach(alphabet, id: \.self) { value in
            ZStack {
                Rectangle()
                    .frame(width: 120, height: 120)
                    .foregroundColor(Color(UIColor.systemIndigo))
                    .cornerRadius(16)
                Text(value.description)
                    .foregroundColor(.white)
                    .font(.title)
                    }
                }
            }
        }
    }
}

Goal:

enter image description here


Solution

  • Load every Cell lazily.

    struct ContentView: View {
        let alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
        let preference = [
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible())
        ]
        var body: some View {
            ScrollView {
                LazyVGrid(columns: preference) {
                    ForEach(alphabet.dropLast(alphabet.count % 3), id: \.self) { value in
                        Cell(value: value)
                    }
                }
                
                LazyHStack {
                    ForEach(alphabet.suffix(alphabet.count % 3), id: \.self) { value in
                        Cell(value: value)
                    }
                }
            }
        }
    }
    

    extracted your Cell view for reusability

    struct Cell: View {
        let value: String
        var body: some View {
            print(value)
           return ZStack {
                Rectangle()
                    .frame(width: 120, height: 120)
                    .foregroundColor(Color(UIColor.systemIndigo))
                    .cornerRadius(16)
                Text(value)
                    .foregroundColor(.white)
                    .font(.title)
            }
        }
    }