LazyHGrid in SwiftUI is similar to LazyVGrid, but instead of arranging its child views in a vertical grid, it arranges them in a horizontal grid. This layout is perfect when you want a horizontally scrollable list of items, organized in multiple rows. Like LazyVGrid, LazyHGrid loads views only when they are about to appear on the screen, which is efficient for handling large datasets.
Key Properties
rows: Defines the number, size, and spacing of rows in the grid.spacing: Controls the spacing between items in the grid.alignment: Manages the vertical alignment of each row within the grid.
Basic Usage
Here’s an example of setting up a LazyHGrid with flexible rows.
import SwiftUI
struct ContentView: View {
let items = Array(1...50) // Sample data
// Define flexible rows with 3 equal-height items per column
let rows = [
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
var body: some View {
ScrollView(.horizontal) { // Horizontal scroll view for LazyHGrid
LazyHGrid(rows: rows, spacing: 16) {
ForEach(items, id: \.self) { item in
Text("Item \(item)")
.frame(width: 80, height: 80)
.background(Color.blue.opacity(0.3))
.cornerRadius(8)
}
}
.padding()
}
}
}
#Preview {
ContentView()
}
Defining Grid Rows
LazyHGrid allows you to define rows using GridItem, giving control over row heights and spacing:
.flexible(): Rows adjust their height to fill the available vertical space..fixed(height): Fixed-height rows that remain constant, useful for a structured layout..adaptive(minimum: height): Automatically adjusts to fit as many rows as possible, given a minimum height.
Example of Adaptive Rows
let adaptiveRows = [
GridItem(.adaptive(minimum: 80)) // Minimum height of 80 for each item
]
With .adaptive, items will be arranged in as many rows as they can fit based on available space, resulting in a responsive layout. Here is the full example:
import SwiftUI
struct ContentView: View {
let items = Array(1...50) // Sample data
// Define adaptive rows
let adaptiveRows = [
GridItem(.adaptive(minimum: 80)) // Minimum height of 80 for each item
]
var body: some View {
ScrollView(.horizontal) { // Horizontal scroll view for LazyHGrid
LazyHGrid(rows: adaptiveRows, spacing: 16) {
ForEach(items, id: \.self) { item in
Text("Item \(item)")
.frame(width: 80, height: 80)
.background(Color.blue.opacity(0.3))
.cornerRadius(8)
}
}
.padding()
}
}
}
Example: Creating a Horizontal Photo Gallery
Here’s a sample use case for LazyHGrid to create a horizontal photo gallery.
import SwiftUI
struct ContentView: View {
let photoURLs: [String] = [
"https://picsum.photos/600",
"https://picsum.photos/500",
"https://picsum.photos/700",
"https://picsum.photos/800",
"https://picsum.photos/id/42/600",
"https://picsum.photos/id/43/600",
]
let rows = [
GridItem(.adaptive(minimum: 100)) // Minimum height 100 for each image
]
var body: some View {
ScrollView(.horizontal) {
LazyHGrid(rows: rows, spacing: 10) {
ForEach(photoURLs, id: \.self) { url in
AsyncImage(url: URL(string: url)) { image in
image
.resizable()
.scaledToFill()
} placeholder: {
ProgressView() // Loading placeholder
}
.frame(width: 100, height: 100)
.clipped()
.cornerRadius(8)
}
}
.padding()
}
}
}

Customizing LazyHGrid Layouts
You can modify each item’s appearance, layout, and interaction within the grid:
ForEach(items, id: \.self) { item in
Text("Item \(item)")
.frame(maxWidth: .infinity, minHeight: 80)
.background(Color.orange.opacity(0.6))
.cornerRadius(12)
}
Benefits of Using LazyHGrid
- Efficient Scrolling: By loading views only when needed,
LazyHGridhandles large datasets more efficiently. - Customizable Layouts:
LazyHGridallows you to control row count and height for responsive horizontal grids. - Memory Optimization: Like
LazyVGrid, it loads only visible items, minimizing memory usage.