Skip to content
DeveloperMemos

Using ForEach in SwiftUI

SwiftUI, ForEach, List1 min read

In SwiftUI, the ForEach construct is a powerful tool that allows us to iterate over collections of data and dynamically create views based on each element. It provides a convenient way to display lists, grids, and other dynamic UI components. In this article, we will explore how to use ForEach effectively in SwiftUI with some examples.

Basics of ForEach

The ForEach construct takes two parameters: the collection of data to iterate over and a closure that defines the view for each element in the collection. The closure receives each element as a parameter and returns a view. Here's a basic example:

1struct ContentView: View {
2 let fruits = ["Apple", "Banana", "Orange"]
3
4 var body: some View {
5 VStack {
6 ForEach(fruits, id: \.self) { fruit in
7 Text(fruit)
8 }
9 }
10 }
11}

In this example, we have an array of fruits, and for each fruit, we create a Text view displaying its name. The id: \.self parameter tells SwiftUI to use each fruit's value as its identifier, ensuring correct view updates when the collection changes.

Identifying Views

To optimize view updates, SwiftUI needs a way to identify each view created by ForEach. By default, SwiftUI uses the id parameter to track changes. In the previous example, id: \.self was used, which means each fruit's value is used as its identifier. If the collection contains elements conforming to the Identifiable protocol, you can omit the id parameter altogether:

1struct Fruit: Identifiable {
2 let id = UUID()
3 let name: String
4}
5
6struct ContentView: View {
7 let fruits = [
8 Fruit(name: "Apple"),
9 Fruit(name: "Banana"),
10 Fruit(name: "Orange")
11 ]
12
13 var body: some View {
14 VStack {
15 ForEach(fruits) { fruit in
16 Text(fruit.name)
17 }
18 }
19 }
20}

In this example, the Fruit struct conforms to the Identifiable protocol by providing a unique identifier using UUID. SwiftUI uses this identifier to track changes in the ForEach loop.

Conditional Views

You can also use ForEach to conditionally create views based on certain criteria. Suppose we have a list of users and want to show only the users with an age greater than 18:

1struct User: Identifiable {
2 let id = UUID()
3 let name: String
4 let age: Int
5}
6
7struct ContentView: View {
8 let users = [
9 User(name: "John", age: 25),
10 User(name: "Sarah", age: 17),
11 User(name: "Mike", age: 30)
12 ]
13
14 var body: some View {
15 VStack {
16 ForEach(users) { user in
17 if user.age > 18 {
18 Text(user.name)
19 }
20 }
21 }
22 }
23}

In this example, the Text view is only created for users with an age greater than 18. This allows us to conditionally display specific content based on the data.

Dynamic Lists

One common use case for ForEach is creating dynamic lists. By combining ForEach with the List view, we can easily display a list of items:

1struct ContentView: View {
2 let todos = ["Task 1", "Task 2", "Task 3"]
3
4 var body: some View {
5 NavigationView {
6 List {
7 ForEach(todos, id: \.self) { todo in
8 Text(todo)
9 }
10 }
11 .navigationBarTitle("Todo List")
12 }
13 }
14}

In this example, we've created a simple todo list using the List view and a ForEach loop. Each todo item from the todos array is displayed as a Text view within the list.

In Closing

The ForEach construct in SwiftUI provides a powerful way to iterate over collections and dynamically create views based on the data. We've explored its basic usage, identifying views, creating conditional views, and building dynamic lists. By harnessing the capabilities of ForEach, you can create flexible and interactive user interfaces in your SwiftUI applications!