SwiftSwiftUISnippetApple
Last updated at 2023-07-10

Easy LazyVGrid for Vertical CollectionView

ClickUp
Note
AI Status
Last Edit By
Last edited time
Jul 10, 2023 11:25 AM
Metatag
Slug
easy-lazyvgrid-for-vertical-collection-view
Writer
Published
Published
Date
Jul 5, 2023
Category
Swift
SwiftUI
Snippet
Apple
We almost always choose UICollectionView when building a dynamic and responsive layout in an iOS app. It has long been the go-to solution. LazyVGrid changed this when it came.
In this tutorial, you will learn how to use the powerful LazyVGrid to build a stunning grid like layout for your SwiftUI app.
🚦
With Network Spy you can monitor, inspect, and modify your network traffic during development. Perfect for debugging and more analysis. 🙌 Join the Waitlist Today! https://mozzlog.com/projects/network-spy

LazyVGrid, what is it?

LazyVGrid allows you to create a grid-based layout. Grid-based means you put the layout in a column-and-row structure. Using LazyVGrid, the cell will dynamically adjust its size and position when the space changes. It is the perfect solution to display a collection of items.
Using UIKit, you usually use UICollectionView with UICollectionFlowLayout or the new UICollectionViewCompositionalLayout to do that. In SwiftUI you can use LazyVGrid to achieve the same result in simple, declarative, and intuitive syntax

Prerequisite

You just need to create a SwiftUI project and open the ContentView.swift file. Of course, it means you need to use an SDK version that supports SwiftUI. The minimum SDK that supports SwiftUI and LazyVGrid are:
  • iOS 14.0+
  • iPadOS 14.0+
  • macOS 11.0+
  • Mac Catalyst 14.0+
  • tvOS 14.0+
  • watchOS 7.0+
  • visionOS 1.0+ Beta
To download the latest Xcode, you can go here.
To create a SwiftUI project. You can follow this article:
This post showing image of cats, if you want to use the same images, you can download here.

Let’s create a basic grid layout

In this tutorial, I want to show a collection of images in a grid layout. Start by defining an array of image names that you want to display in a grid.
To use LazyVGrid to create the grid layout, you need to replace the existing body property of ContentView with this code. You can copy and paste this code.
struct ContentView: View { // create cat1 to cat10 images in Assets directory let images = [ "cat1", "cat2", "cat3", "cat4", "cat5", "cat6", "cat7", "cat8", "cat9", "cat10" ] let columns: [GridItem] = [ GridItem(.adaptive(minimum: 100), spacing: 8), ] var body: some View { LazyVGrid(columns: columns, spacing: 8) { ForEach(images, id: \.self) { image in Image(image) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 100, height: 100) .clipped() .border(Color.red) } } .frame(width: 300, height: 500) .border(Color.black) .padding() } }
In the above code, the grid takes columns as an argument in the form of a GridItem array. We use GridItem.Size.adaptive in order to allow the cell to resize automatically if the width is higher than 100 points.
Creating grid cells is easy. You can use the ForEach view to iterate over the image array. We create the Image view for each image item. Because our images are an asset, the Image view will show our images quickly.
Here we show 10 images. In a standard view, it shows all images without a problem. But if and the available space isn’t enough, we need to make the grid show all the contents. To fix this issue, we can use ScrollView as the grid container, so it is scrollable when the content exceeds the available space.
var body: some View { ScrollView { LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))]) { // ... } } .frame(width: 300, height: 500) .border(Color.black) .padding() }
Above code wrap the LazyVGrid inside a ScrollView. This will enable the grid to be scrolled if it exceeds ScrollView frame.

Grid Layout Customization

Customization is available as part of the LazyVGrid parameter. It allows us to layout the grid to suit our specific needs. Now we will explore some basic customization that we can do:

Custom number of columns

If we want to specify how many columns our grid should have, then we assign GridItem(.flexible()) for element in columns array. This will update the number of column to match the columns array count.
let columns: [GridItem] = [ GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()), ]
The above code will create a grid with three columns.

Adjusting the Line Spacing

We don't want the grid cells line spacing to stick to each other. This can be done with line-item grid spacing. We can modify this spacing in LazyVGrid. It represents the distance between adjacent elements. We rewrite the LazyVGrid code to include spacing with this:
LazyVGrid(columns: columns, spacing: 100) { // ... }
In that code, we've set the spacing to 100 points. So big eh?

Defining Item Sizes

In some cases, we want to create custom sizes for specific columns. This depends on what your design wants to be. LazyVGrid allows this custom size so that your cell can have a different width or height. To do that, we change the code to this:
LazyVGrid(columns: [ GridItem(.adaptive(minimum: 100)), GridItem(.fixed(200)) ])
In this code, the first column will have a minimum width of 100 points, while the second column will have a fixed width of 200 points.

Handling Interactions

In UICollectionView, you use cellDidSelectAt in UICollectionViewDelegate and respond to the user’s tap accordingly. In LazyVGrid, we can use these to handle user taps:

Adding a Tap Gesture

If we want to add interactivity to a specific area of the cell when user performs tap, we use the .onTapGesture modifier. This will invoke the closure when user tap the image.
Image(imageName) .resizable() .aspectRatio(contentMode: .fit) .onTapGesture { print("tap") }
In the action closure, you can implement the desired behavior when the user taps on the image.

Adding a Long Press Gesture

Long press gesture is also available. You can use .onLongPress gesture modifier to do that.
Image(imageName) .resizable() .aspectRatio(contentMode: .fit) .onLongPressGesture { print("owh got long press") }
In the closure, you can implement the desired behavior when the user performs a long press on the image.

Conclusion

The UICollectionView era is long gone. Oh, no. Not yet. But in SwiftUI, it is better to use LazyVGrid. It is a powerful tool for creating dynamic and responsive grid layouts. Its flexible syntax offers a seamless alternative to UICollectionView for building a declarative user interface.

What To Do Next

Now that you have learned how to use LazyVGrid, you can use it in your app. You can build a sample project. If you need a horizontal layout, you can check out LazyHGrid's tutorial!
Read About LazyHGrid

Discussion (0)

Related Posts