Hello everyone,
Welcome back to Learning SwiftUI, this is issue #9.
This week I thought about writing about more than just code examples for this newsletter. So I started working on a piece but realized I will not be able to finish it before the end of this week. So for this issue, I decided to go for the ForEach loop. But for the long term future, I plan to write about more things here other than code examples.
So let’s go through some ForEach examples.
The ForEach instance can iterate over arrays, meaning that it will produce views of each object that is provided in the array. One thing to keep in mind, the items in the array need to conform to the Identifiable protocol, if it does not, you need to provide an id for all items in the array to the ForEach initializer.
To be honest, I never thought about that, so I learned something new here. Which is the beauty of exploring topics in more detail.
Let’s try and set up an array in ForEach that do not conform to the Identifiable protocol.
struct ForEachExamples: View {
var items = ["Hello", "Hello again", "Hello three"]
var body: some View {
VStack {
ForEach(items) { item in
Text(item)
}
}
}
}
With this code, you should get the following error message:
Why do we get this error? The reason, as mentioned earlier, is because our array named items does not conform to the Identifiable protocol. And if it does not, as in this case, we need to add an id in the ForEach initializer. So let's do that right away.
struct ForEachExamples: View {
var items = ["Hello", "Hello again", "Hello three"]
var body: some View {
VStack {
ForEach(items, id: \.self) { item in
Text(item)
}
}
}
}
And now the code compiles, as you can see in the picture above. This is how the text will line up since we have set our ForEach within a vertical stack. Try changing it to an HStack instead and see what happens, or watch the next example below where an HStack is used.
Want to learn more about SwiftUI animations?
I created a book for anyone new to SwiftUI that wants to develop their SwiftUI animation skills. The book cover the basics and more advance techniques to animating objects and views in SwiftUI. You can check it out by clicking the link below:
Learning SwiftUI Animations - The Beginner Roadtrip
Two minor examples from the book:
You can also add the array within the ForEach initializer as well. Which will reduce the code, here is an example:
struct ForEachExamples: View {
var body: some View {
HStack {
ForEach(0..<10, id: \.self) { _ in
Rectangle()
.foregroundColor(.green)
}
}
}
}
In this example, we have specified the array of items within the ForEach initializer instead. Since we are working with a rectangle here, we do not need to specify an item, we can just use "_" instead and we will get 10 rectangles lining up horizontally as we set them in a HStack.
Alright, so I said before that the ForEach needs to conform to the Identifiable protocol. So far we only covered how to use it in the ForEach initializer. We could also set up a struct that conforms to the Identifiable protocol instead. This will give us a little more flexibility with how we can adjust our objects within the ForEach instance.
struct ForEachExamples: View {
var textItem: [TextItems] = TextList.textList
var body: some View {
VStack(spacing: 20) {
ForEach(textItem) { item in
Text(item.text)
.foregroundColor(item.color)
.font(item.font)
}
}
.fontWeight(.semibold)
}
}
struct TextItems: Identifiable {
let id = UUID()
var text: String
var color: Color
var font: Font
}
struct TextList {
static let textList = [
TextItems(text: "Hello", color: Color.green, font: .largeTitle),
TextItems(text: "World", color: Color.red, font: .title),
TextItems(text: "What's", color: Color.blue, font: .title2),
TextItems(text: "Up?", color: Color.purple, font: .title3)
]
}
As you can see in the example above, we have created an struct called TextItems that conforms to the Identifiable protocol. Which means we have to add an UUID() property.
Then we need to set up another struct and create an array of our TextItems and set different strings, fonts and colors. Then we call it in ForEachExamples and present it in a ForEach loop. As you can see in the code, we no longer need to provide an id in the ForEach initializer as the TextItems struct already conforms to the Identifiable protocol.
That was it for this issue. What do you think? Do you have another way of doing this? Let me know in the comments here or on Twitter.
Have a nice day.
Mr SwiftUI