← All courses

Lists, ForEach & Identifiable

🗓 May 31, 2026 ⏱ 2 min read

The List view

List is SwiftUI’s scrolling, table-style container. It’s efficient (it reuses rows like UIKit’s table view) and gives you platform features like swipe-to-delete and sections almost for free.

struct FruitList: View {
    let fruits = ["Apple", "Mango", "Kiwi"]
    var body: some View {
        List(fruits, id: \.self) { fruit in
            Text(fruit)
        }
    }
}

Why identity matters: Identifiable

SwiftUI needs to tell items apart so it can update, insert, delete and animate them correctly. For simple values you pass id: \.self, but for your own data types it’s cleaner to make them Identifiable by giving them an id.

struct User: Identifiable {
    let id = UUID()       // a unique identity
    let name: String
}

struct UsersView: View {
    let users = [User(name: "Anand"), User(name: "Priya")]
    var body: some View {
        List(users) { user in     // no id: needed — it's Identifiable
            Text(user.name)
        }
    }
}

If identity is wrong or unstable, SwiftUI can animate the wrong rows or lose state — so always give list data a stable identity.

ForEach inside other containers

List is one use of ForEach, but you can use ForEach inside any container (a VStack, a LazyVStack) to repeat views over data.

ScrollView {
    LazyVStack(alignment: .leading) {
        ForEach(users) { user in
            Text(user.name).padding(.vertical, 4)
        }
    }
}

LazyVStack only builds visible rows (good for very long lists), whereas a plain VStack builds them all.

Sections and swipe actions

List {
    Section("Team") {
        ForEach(users) { user in Text(user.name) }
            .onDelete { indexSet in /* remove items */ }
    }
}

Common mistakes

  • Using array index as identity — it shifts when items move, breaking animations and state. Use a stable id.
  • Using a plain VStack for hundreds of rows — use List or LazyVStack.
  • Forgetting Identifiable and littering id: \.self everywhere.
Summary: Use List (or ForEach in a LazyVStack) to show collections. Give your data a stable identity via Identifiable so SwiftUI updates and animates the right rows.