SwiftUI LazyVStack

In SwiftUI, the LazyVStack is a container that arranges its child views vertically. Unlike a regular VStack, the LazyVStack only loads the views that are currently visible on the screen. This makes it an efficient choice when working with large data sets, as it optimises memory and performance.

The LazyVStack is ideal for building vertically scrolling lists or grids with large or dynamic content.


Basic Syntax of LazyVStack

The basic syntax of LazyVStack is as follows:

</>
Copy
ScrollView {
    LazyVStack {
        Content1()
        Content2()
        Content3()
    }
}

Here:

  • ScrollView: Enables vertical scrolling of the content. Refer ScrollView in SwiftUI.
  • LazyVStack: Arranges the child views vertically and loads them lazily as they appear on screen.
  • Content1, Content2, Content3: Views displayed in the stack.

Examples of LazyVStack

Let’s explore practical examples that demonstrate how to use LazyVStack in SwiftUI effectively.


Example 1: Basic LazyVStack

This example demonstrates how to create a simple LazyVStack with static content.

Code Example:

</>
Copy
import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 10) {
                ForEach(1...20, id: \.self) { index in
                    Text("Item \(index)")
                        .frame(maxWidth: .infinity)
                        .padding()
                        .background(Color.blue.opacity(0.2))
                        .cornerRadius(8)
                }
            }
            .padding()
        }
    }
}

Xcode Screenshot:

Example for Basic LazyVStack

Explanation:

  • The ScrollView enables vertical scrolling.
  • The LazyVStack contains 20 text views, each created dynamically using ForEach.
  • Each item is styled with padding, a background color, and rounded corners.

Result: A vertically scrolling list of 20 items, with optimized lazy loading for better performance.


Example 2: LazyVStack with Images

This example arranges a list of images vertically with lazy loading.

Code Example:

</>
Copy
import SwiftUI

struct ContentView: View {
    let images = ["star", "heart", "circle", "square", "triangle"]

    var body: some View {
        ScrollView {
            LazyVStack(spacing: 15) {
                ForEach(0..<50) { index in
                    HStack {
                        Image(systemName: images[index % images.count])
                            .resizable()
                            .frame(width: 50, height: 50)
                            .foregroundColor(.purple)

                        Text("Image \(index + 1)")
                            .font(.headline)
                            .padding(.leading, 10)
                    }
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.gray.opacity(0.1))
                    .cornerRadius(8)
                }
            }
            .padding()
        }
    }
}

Xcode Screenshot:

Example for LazyVStack with Images

Explanation:

  • The ForEach loop dynamically generates 50 rows.
  • Each row includes an SF Symbol image and a corresponding text label.
  • The LazyVStack ensures that only visible views are loaded lazily.

Result: A scrollable list of images and labels, arranged vertically, with lazy loading.


Example 3: LazyVStack with Dynamic Content

This example demonstrates a dynamic LazyVStack where data can be added interactively.

Code Example:

</>
Copy
import SwiftUI

struct ContentView: View {
    @State private var items = Array(1...10)

    var body: some View {
        VStack {
            ScrollView {
                LazyVStack(spacing: 10) {
                    ForEach(items, id: \.self) { item in
                        Text("Item \(item)")
                            .frame(maxWidth: .infinity)
                            .padding()
                            .background(Color.green.opacity(0.2))
                            .cornerRadius(8)
                    }
                }
                .padding()
            }

            Button("Add Item") {
                items.append(items.count + 1)
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)
        }
    }
}

Xcode Screenshot:

Explanation:

  • The @State variable items holds the dynamic list of numbers.
  • Each tap on the “Add Item” button appends a new item to the list.
  • The LazyVStack updates dynamically to include new items.

Result: A scrollable, vertically arranged list where new items are added dynamically.


Example 4: Nested LazyVStack

This example demonstrates nested LazyVStack views to create sections.

Code Example:

</>
Copy
import SwiftUI

struct ContentView: View {
    let sections = ["Section 1", "Section 2", "Section 3"]

    var body: some View {
        ScrollView {
            LazyVStack(spacing: 20) {
                ForEach(sections, id: \.self) { section in
                    VStack(alignment: .leading) {
                        Text(section)
                            .font(.title)
                            .padding(.bottom, 5)

                        LazyVStack(spacing: 10) {
                            ForEach(1...5, id: \.self) { index in
                                Text("\(section) - Item \(index)")
                                    .frame(maxWidth: .infinity)
                                    .padding()
                                    .background(Color.orange.opacity(0.2))
                                    .cornerRadius(8)
                            }
                        }
                    }
                }
            }
            .padding()
        }
    }
}

Xcode Screenshot:

Example for Nested LazyVStack

Explanation:

  • Each section title is displayed with a Text view.
  • Nested LazyVStack views display five items under each section.

Result: A scrollable view with sections, where each section contains a nested list of items.


Conclusion

The LazyVStack in SwiftUI provides an efficient way to display large vertical lists while optimizing performance through lazy loading. By combining it with ScrollView and dynamic content, you can build flexible, interactive, and performant vertical layouts.