简体   繁体   中英

How could I use a SwiftUI LazyVGrid to create a staggered grid?

I'm trying to implement a view that contains a LazyVGrid of staggered images in a grid- as seen in the below Pinterest feed:

在此处输入图像描述

I am aware of the WaterfallGird library but I was wondering if there would be a way to implement this functionality with a LazyGrid, instead of an ordinary V/HGrid.

  1. Split your array into the number of columns you need.
  2. Inside your LazyVGrid create 2 VStacks.
  3. Drop a ForEach in both VStacks and use each of your arrays you created earlier to fill them out.
  4. That's it

A rough example as follows...

// split array
let splitArrays = ([TileItem], [TileItem])

ScrollView {
    LazyVGrid(*setup GridItems here*) {
        VStack {
            ForEach(splitArrays.0) { tile in
                Image(tile.image)
            }
        }
        VStack {
            ForEach(splitArrays.0) { tile in
                Image(tile.image)
            }
        }
    }
}

It's likely that this isn't very performant, but it should be able to do what you're after.

Beau Nouvelle solution is working, however, it's buggy and glitchy at least of me. Instead of using LazyVGrid if we use HStack with alignment: .top It works better.

Here is the view

var body: some View {

        HStack(alignment: .top) {            
            LazyVStack(spacing: 8) {
                ForEach(splitArray[0]) {...}
            }
            
            LazyVStack(spacing: 8) {
                ForEach(splitArray[1]) {...}
            }
        }
    }

Here is the code to split the array

    private var splitArray: [[Photo]] {
        var result: [[Photo]] = []
        
        var list1: [Photo] = []
        var list2: [Photo] = []
        
        photos.forEach { photo in
            let index = photos.firstIndex {$0.id == photo.id }
            
            if let index = index {
                if index % 2 == 0  {
                    list1.append(photo)
                } else {
                    list2.append(photo)
                }
            }
        }
        result.append(list1)
        result.append(list2)
        return result
        
    }

I know this is not performance but so far only working solution I found.

Here is the full source code

在此处输入图像描述

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