ForEach in SwiftUI

ForEach in SwiftUI

·

4 min read

SwiftUI is a declarative way to build user interfaces for Apple platforms. One of its core features is the ForEach view, which allows developers to loop over a collection of data and create a view for each element in that collection. In this blog post, we’ll explore the various ways you can use the ForEach view in SwiftUI.

The code in this post is available here.

Basic Usage of ForEach

The simplest usage of the ForEach view is to create a view for each element in an array. Here's an example:

let numbers = [1, 2, 3, 4, 5]

var body: some View {
    List {
        ForEach(numbers, id: \.self) { number in
            Text("\(number)")
        }
    }
}

In the example above, we’re creating a view for each element in the numbers array. The id parameter tells SwiftUI how to uniquely identify each element in the array. In this case, we’re using the \.self key path, which means that SwiftUI should use the element itself as its identifier.

Using ForEach with Identifiable Data

If the data you’re looping over conforms to the Identifiable protocol, you can omit the id parameter and SwiftUI will use the element’s identifier automatically. Here’s an example:

struct Person: Identifiable {
    let id = UUID()
    let name: String
}

let people = [Person(name: "Alice"), Person(name: "Bob"), Person(name: "Charlie")]

var body: some View {
    List {
        ForEach(people) { person in
            Text("\(person.name)")
        }
    }
}

In the example above, we’re looping over an array of Person objects, which conform to the Identifiable protocol. Since the Person objects have a unique identifier (id), we can omit the id parameter in the ForEach view.

Using ForEach with a Range

You can also use the ForEach view to loop over a range of numbers:

var body: some View {
    List {
        ForEach(0..<10) { number in
            Text("\(number)")
        }
    }
}

In the example above, we’re creating a view for each number in the range 0..<10.

Using ForEach with a Conditional Statement

Sometimes you may want to filter the data you’re looping over based on a conditional statement. You can use the if statement to achieve this:

let numbers = [1, 2, 3, 4, 5]

var body: some View {
    List {
        ForEach(numbers, id: \.self) { number in
            if number % 2 == 0 {
                Text("\(number)")
            }
        }
    }
}

In the example above, we’re looping over an array of numbers and only creating a view for those that are even.

Using ForEach with Indices

If you need to access the index of each element in the array, you can use the indices property of the array. Here’s an example:

struct Person: Identifiable {
    let id = UUID()
    let name: String
}

let people = [Person(name: "Alice"), Person(name: "Bob"), Person(name: "Charlie")]

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

In the example above, we’re using the indices property of the people array to loop over the indices of each Person element. We can then use the index parameter to access the corresponding element in the array.

Shorthand Syntax

In SwiftUI's ForEach, the $0 shorthand syntax refers to the current element being processed in the loop.

This shorthand syntax is commonly used when you want to access the properties of each element in the loop. The $0 is a placeholder for the current element and you can use dot notation to access its properties.

Here's an example of using the $0 shorthand syntax in a ForEach loop:

struct ContentView: View {
     struct Person: Identifiable, Hashable {
        let id = UUID()
        let name: String
    }

    let people = [Person(name: "Alice"), Person(name: "Bob"), Person(name: "Charlie")]

    var body: some View {
        List {
            Text("General Syntax: ").bold()
            ForEach(people, id: \.self) { person in
                Text(person.name)
            }
            Text("Shorthand Syntax: ").bold()
            ForEach(people, id: \.self) {
                Text($0.name)
            }
        }
    }
}

In the example above, we have an array of Person called people and we are using ForEach to create a Text view for each element in the array.

In the first loop, we are using the name property of each person to display the name, which is the conventional way of using ForEach. In the second loop, we are using the $0 shorthand syntax to directly access the name property without assigning the person instance to a variable first.

Both loops produce the same result, but the second loop is a more concise and readable way of using ForEach.

Conclusion

The ForEach view in SwiftUI is a powerful tool for looping over collections of data and creating views dynamically. It can be used to handle a large number of similar views, ie. since a SwiftUI view can contain up to 10 child views, however with ForEach we can declare similar views for the items from the same data source as just one view.

That’s all of today’s post. I hope it helps and let me know if it is by leaving a comment. Don’t forget to subscribe to my newsletter if you’d like to receive posts like this via email.

I’ll see you in the next post!