SwiftSwiftUISnippetApple
Last updated at 2023-07-10

Easy LazyHGrid for Horizontal CollectionView

ClickUp
Note
AI Status
Last Edit By
Last edited time
Jul 10, 2023 04:17 PM
Metatag
Slug
easy-lazyhgrid-for-horizontal-collection-view
Writer
Published
Published
Date
Jul 5, 2023
Category
Swift
SwiftUI
Snippet
Apple
If you have read LazyVGrid, you must have known why we use this view to replace UICollectionView. The Grid View in Swift offers powerful features to make building grid layouts more intuitive and seamless. You will also learn the same with LazyHGrid.
If you haven’t yet read LazyVGrid, Check out the its tutorial!
In this tutorial, you will learn how to use the powerful LazyHGrid 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

LazyHGrid, what is it?

With LazyHGrid, you can make a grid-based design. When you use a grid-based layout, you lay out the children in a column and row. With LazyHGrid, the cell will automatically resize and relocate itself to fit the new confines. It's the best way to show off a curated collection.
The difference between LazyHGrid and LazyVGrid is that the former will lay out the cells horizontally rather than vertically.
UICollectionView and either UICollectionFlowLayout or the brand-new UICollectionViewCompositionalLayout are commonly used in UIKit for this purpose. To get the same effect in SwiftUI with declarative and intuitive syntax, you can use LazyHGrid.

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

The goal of this tutorial is to demonstrate how to display a set of images on a grid. To get started, compile a list of all the images' names you intend to display in a grid.
The body property of ContentView must be replaced with this code in order to use LazyHGrid to generate the grid layout. You can use this code as a template.
struct ContentView: View { // create cat1 to cat10 images in Assets directory let images = [ "cat1", "cat2", "cat3", "cat4", "cat5", "cat6", "cat7", "cat8", "cat9", "cat10" ] let rows: [GridItem] = [ GridItem(.adaptive(minimum: 100), spacing: 8), ] var body: some View { LazyHGrid(rows: rows, 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: 300) .border(Color.black) .padding() } }
In the preceding code, the GridItem array is used as the rows argument for the grid. If the container width is greater than 100pt, GridItem.Size.adaptive will automatically make the cell bigger.
You want to show each of the cat images. 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.
As you can see from the screenshoot, sometimes the cell is go out of the screen. There are some corners from the cat image not shown to the user. This this can be a problem when you need to show every pixel of the cell to the user. To overcome this issue, you can employ ScrollView to make the LazyHGrid scrollable.
var body: some View { ScrollView { LazyHGrid(rows: rows) { // ... } } .frame(width: 300, height: 500) .border(Color.black) .padding() }

Grid Layout Customization

The LazyHGrid parameter provides options for customization. This can help you when there is specific requirement on how the cells should be shown to user.
Let's now get into some fundamental customization possibilities we can explore:

Adjusting the Spacing

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

Defining Item Sizes

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

Custom number of rows

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

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.
Read More About UICollectionView

What To Do Next

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

Discussion (0)

Related Posts