When you’re starting with SwiftUI, one of the first loops you’ll use is ForEach
. It’s handy for creating repeated views, like a list of texts or buttons. But if you’ve tried using it, you might have run into a compiler error that looks confusing at first glance.
The Problem Code
Here’s the code many beginners write:
var body: some View {
VStack {
ForEach(1...5) { i in
Text("i is \(i)")
}
Spacer()
}
}
At first, this seems fine. We’re looping from 1 to 5 and creating a Text
for each number. But SwiftUI gives us an error:
Type ‘Int’ does not conform to ‘Identifiable’
Why is that happening?
Why SwiftUI Needs an id
SwiftUI is declarative. That means instead of telling SwiftUI how to draw each frame, we describe what the UI should look like, and SwiftUI decides the most efficient way to update the screen.
To do this efficiently, SwiftUI must be able to track which view corresponds to which piece of data. If the data changes, SwiftUI needs a way to know:
- Should it update an existing view?
- Should it remove a view?
- Should it create a new view?
This is where identifiers (id
) come in. Each item in a ForEach
needs a unique identifier so SwiftUI can match data to views during updates.
Fixing the Code with id: \.self
Since Int
doesn’t conform to Identifiable
, SwiftUI doesn’t know how to uniquely identify each number in the range. The fix is to explicitly provide an id
:
var body: some View {
VStack {
ForEach(1...5, id: \.self) { i in
Text("i is \(i)")
}
Spacer()
}
}
Here’s what’s happening:
id: \.self
tells SwiftUI: “Use the number itself as the unique identifier.”- Now SwiftUI knows that
1
,2
,3
, etc. are unique and can track them properly.
✅ Problem solved!
When You Don’t Need id
If your data items are already identifiable, you don’t need to specify id
. For example, consider a list of custom models:
struct Person: Identifiable {
let id = UUID()
let name: String
}
let people = [
Person(name: "Ali"),
Person(name: "Sara")
]
var body: some View {
ForEach(people) { person in
Text(person.name)
}
}
Here, each Person
already has a unique id
, so SwiftUI automatically uses it to track the views.
Key Takeaways
- SwiftUI needs identifiers to track items in a
ForEach
loop. Int
is notIdentifiable
, so you must provideid: \.self
when looping over ranges like1...5
.- For custom models, make them conform to
Identifiable
or provide a unique property as theid
.
Final Thoughts
If you’re new to SwiftUI, this can feel like an annoying detail. But once you understand why id
is needed, it makes sense. SwiftUI isn’t just looping; it’s efficiently updating your UI by tracking which data belongs to which view.
So next time you see the error “Type ‘Int’ does not conform to ‘Identifiable’”, you’ll know exactly what to do!