How to Create a List in SwiftUI

Use a List in SwiftUI when your app needs to display scrollable rows of data like settings, messages, products, or task items. List is the standard way to render dynamic vertical collections on Apple platforms.

What you’ll build or solve

You’ll learn how to create a List in SwiftUI with static rows, dynamic arrays, and identifiable models. You’ll also know when ScrollView is a better fit.

When this approach works best

This approach is the right choice when the UI needs reusable rows, separators, swipe actions, or built-in list behaviors.

Common real-world scenarios include:

  • Settings screens
  • Todo apps
  • Chat inboxes
  • Product feeds
  • Course lesson lists

This is a bad idea when the layout needs fully custom freeform positioning without standard list behavior.

Prerequisites

You only need:

  • Basic SwiftUI views
  • Arrays
  • ForEach familiarity

Step-by-step instructions

Step 1: Create a static List

The simplest version uses hardcoded rows.

import SwiftUI

struct SettingsView: View {
    var body: some View {
        List {
            Text("Profile")
            Text("Notifications")
            Text("Billing")
        }
    }
}

This automatically creates a scrollable list with native row styling.

Step 2: Render dynamic array data

The most common real-world pattern is looping through data.

struct LessonsView: View {
    let lessons = ["HTML", "CSS", "SwiftUI"]

    var body: some View {
        List(lessons, id: \.self) { lesson in
            Text(lesson)
        }
    }
}

This keeps the UI synced with the array.

Step 3: Use custom models with Identifiable

For real apps, models scale better.

struct Course: Identifiable {
    let id = UUID()
    let title: String
}

struct CoursesView: View {
    let courses = [
        Course(title: "Swift Basics"),
        Course(title: "iOS Layouts")
    ]

    var body: some View {
        List(courses) { course in
            Text(course.title)
        }
    }
}

This is the cleanest production-ready pattern.

What to look for:

  • List creates native scrolling rows
  • Arrays render cleanly
  • Identifiable models scale best
  • Great for settings and feeds
  • Use ScrollView for fully custom layouts

Examples you can copy

Static menu

List {
    Text("Home")
    Text("Profile")
}

Dynamic strings

List(tags, id: \.self) { tag in

Identifiable models

List(users) { user in

Common mistakes and how to fix them

Mistake 1: Missing stable IDs

What the reader might do:

Use custom models without Identifiable.

Why it breaks: SwiftUI cannot track row identity properly.

Corrected approach:

Conform the model to Identifiable.

Mistake 2: Using List for custom grids

What the reader might do:

Force complex card layouts into rows.

Why it breaks: list styling becomes restrictive.

Corrected approach:

Use ScrollView + LazyVGrid.

Mistake 3: Using unstable IDs

What the reader might do:

Use changing computed IDs.

Why it breaks: row updates become glitchy.

Corrected approach:

Use persistent stable IDs.

Troubleshooting

If rows fail to update correctly, verify stable IDs.

If the layout feels restrictive, switch to ScrollView.

If separators look wrong, customize the list style.

If the data is dynamic, ensure the array updates are observable.

Quick recap

  • Use List for native scrollable rows
  • Great for settings and feeds
  • Use stable IDs
  • Prefer Identifiable models
  • Use ScrollView for fully custom layouts