When SwiftUI was introduced back in 2019, many other iOS developers and I found it to be a solid step forward for the platform. It represented a significant change in how developers should build user interfaces (UX) for the Apple ecosystem, and it brought the framework to the forefront of the industry. It was an exciting time to be a fan of everything Cupertino.
Apple introduced a lot of things back then with SwiftUI, and since then, many things have changed and evolved with it. Yet it remains as familiar and approachable as ever to this day.
One of the many introductions to the UX design framework was the ForEach view structure. That will be the subject of this article.
This article aims to provide you with all you need to level up your UI development with SwiftUI using the ForEach view structure. Additionally, this article will serve as an introductory resource for developing with SwiftUI and XCode with some helpful examples and actionable guidance.
By the end of this article, you should feel comfortable implementing design solutions in SwiftUI with the ForEach view structure and leverage all its potential.
If you have no experience with SwiftUI, don't worry. We'll show you what need to know to get you going.
Introduction to SwiftUI
SwiftUI is Apple's latest framework for building UX for iOS, macOS, watchOS, and tvOS. With it, developers can build design solutions rapidly and empower their applications with modern design patterns.
Unlike UIKit and AppKit, SwiftUI is a cross-platform framework. This means developers can build a view structure that works for both iOS and macOS. All you need to deploy your code on any Apple platform is to master one language (Swift) and the framework.
The framework provides all the necessary components to build elegant user interfaces. And the best part is that they're familiar. Chances are you have worked with lists, buttons, pickers, and stacks in some UIKit project or even on entirely different platforms.
Let's see it in action.
Open XCode and create a new iOS SwiftUI project. Call it "MyListProject".
Great! Now, notice that you have a class called "ContentView" where the titular "Hello World!" statement lives.
This basic SwiftUI structure contains all the necessary elements to render and display a screen. It has a 'View' container, represented by the body structure, and in it, a single 'Text' view element with the greeting message. Simple.
Don't worry about the second structure. This is the preview structure, and it's there to allow XCode to generate a live preview of your code. So, you won't need to touch this for now.
When you want to design a screen on SwiftUI, you have to add elements to the body structure. You do that by simply stacking them in containers, lists, or other elements, which can respond to the screen and other elements dynamically. Think of it as an organic structure that responds to all its components based on their rules. These rules, or modifiers, allow you to alter how the element is displayed and provide context to its structure. One example is the '.padding()' modifier, which basically adds padding to the 'Text' element. Its default value is 20.
All view elements have modifiers, and some are common between all elements, like padding, width, and frame. However, other modifiers only exist on specific elements, like font and border.
Finally, some elements exist to give context to SwiftUI about how to display its children. One of these is the VStack, or vertical stack, which organizes all child elements vertically. These are the view structure elements, and the ForEach is one of them.
SwiftUI ForEach 101
Despite its name, the ForEach holds little resemblance with the typical ForEach command that you might be familiar with. Instead, as the ForEach is a view structure, and its purpose is to compute views on demand from an underlying data collection.
This means that, much like the VStack, the ForEach view structure gives context to SwiftUI about how to display its children elements, but it allows you to create the child elements from a collection of data dynamically.
Let's see an example.
If I wanted to display three text views on the screen organized vertically, I could simply create three 'Text' elements and put them inside a VStack. There you go, my job is done.
But as you probably know, this is not a valid solution, especially not for dynamic data.
Ok, let's do it right this time.
What have we done here?
First, the ForEach requires your data to conform to the 'Identifiable' protocol. This means that for raw data, you need to create a new structure type that wraps it and defines an 'ID' that the ForEach can use to distinguish between elements. So you have the 'MyData' structure addressing that requirement.
Second, the array of data now has to contain instances of this structure, which is pretty straightforward.
The ForEach view structure has to live under a parent view structure so it can inform how to display its children. In this case, since it's contained under a VStack, the items are stacked vertically.
Finally, as you can see, the ForEach syntax looks quite similar to a standard ForEach directive on Swift. You provide the data and a prototype that it uses to render the view elements. In this case, that prototype is the 'Text' element.
Pretty simple, right?
Well, we can make it even simpler.
More Examples of ForEach in SwiftUI
Check this out:
Here, the data is back to just being an array of strings, but the ForEach still needs an identifier, so we specified that the 'self' of the data should be used as an identifier. What this means is that each item serves as its own key.
Mind you, this only works because each string is unique. So you should not use this alternative if you don't know if the data is already unique.
That is pretty great. But what if you just want to display a static element multiple times?
Well, we can simplify even further.
As you can see, all you need to do is to provide an array of items, in this case, a dynamic array constructed from a range between 0 and 2, that can be used as an index and that provides the static data to the prototype and ignores the index. Voila.
With a declarative syntax, recognizable elements, and an intuitive structure pattern, there are many similarities between SwiftUI and most of the popular modern platforms in the industry. If you come from something like React or Kotlin, some of the structure and concepts in this article will still be familiar enough that you should understand what the code does. The ForEach is one of the most recognizable syntax structures out there, and it's incredibly powerful when used correctly.
Nevertheless, to ensure that your work is free of bugs and issues, you must use a reliable testing workflow like Waldo's zero-code testing workflow solution. There is no need to create complicated and messy testing workflows. Just set it up, and it's good to go. You can learn more about it here.