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 syntaxPrerequisite
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