Published on

SwiftUI Cheat Sheet: Looping Through Lists with ForEach 🙌🏻

Authors

Your Go-To Guide for Using ForEach with Index in SwiftUI

SwiftUI’s ForEach is a versatile tool that simplifies creating views from collections of data. This cheat sheet will walk you through various ways to use ForEach, including how to access indices while looping through lists.

Basic ForEach Usage

To start, let's look at the simplest use of ForEach to display items in a list:

import SwiftUI

struct ContentView: View {
    let items = ["Apple", "Banana", "Cherry"]

    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text(item)
            }
        }
    }
}

In this example, ForEach iterates over the items array and displays each item as a Text view.

ForEach with Index

To access the index of each item in the list, use the enumerated() method:

import SwiftUI

struct ContentView: View {
    let items = ["Apple", "Banana", "Cherry"]

    var body: some View {
        List {
            ForEach(Array(items.enumerated()), id: \.element) { index, item in
                Text("\(index): \(item)")
            }
        }
    }
}

Here, Array(items.enumerated()) converts the enumerated sequence into an array, allowing ForEach to use both the index and the item.

ForEach with Binding Collection

If you're working with a mutable collection, you can directly access indices:

import SwiftUI

struct ContentView: View {
    @State private var items = ["Apple", "Banana", "Cherry"]

    var body: some View {
        List {
            ForEach(items.indices, id: \.self) { index in
                Text("\(index): \(items[index])")
            }
        }
    }
}

Using items.indices, you get a range of valid indices, and ForEach iterates over these indices to access items.

Dynamic List with Add and Delete Actions

For more dynamic interactions, such as adding and deleting items:

import SwiftUI

struct ContentView: View {
    @State private var items = ["Apple", "Banana", "Cherry"]

    var body: some View {
        VStack {
            List {
                ForEach(Array(items.enumerated()), id: \.element) { index, item in
                    HStack {
                        Text("\(index): \(item)")
                        Spacer()
                        Button(action: {
                            items.remove(at: index)
                        }) {
                            Image(systemName: "trash")
                        }
                    }
                }
            }
            Button(action: {
                items.append("New Item")
            }) {
                Text("Add Item")
            }
        }
    }
}

In this example, each item has a delete button, and there's an "Add Item" button to dynamically add new items to the list.

Nested ForEach Loops

You can also nest ForEach loops for more complex data structures:

import SwiftUI

struct ContentView: View {
    let categories = [
        "Fruits": ["Apple", "Banana", "Cherry"],
        "Vegetables": ["Carrot", "Peas", "Potato"]
    ]

    var body: some View {
        List {
            ForEach(categories.keys.sorted(), id: \.self) { category in
                Section(header: Text(category)) {
                    ForEach(categories[category]!, id: \.self) { item in
                        Text(item)
                    }
                }
            }
        }
    }
}

This example displays items grouped by category, demonstrating nested ForEach loops to handle complex data structures.

Conclusion

SwiftUI's ForEach is a powerful and flexible way to iterate over collections, whether you need simple lists or more complex, dynamic interfaces. By understanding how to use ForEach with indices and binding collections, you can create rich, interactive user experiences with minimal code.

Dive into these examples, experiment with your data, and see how ForEach can simplify your SwiftUI development!