ForEach
A structure that computes views on demand from an underlying collection of identified data.
Declaration
struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : HashableMentioned in
Overview
Use ForEach to provide views based on a RandomAccessCollection of some data type. Either the collection’s elements must conform to Identifiable or you need to provide an id parameter to the ForEach initializer.
The following example creates a NamedFont type that conforms to Identifiable, and an array of this type called namedFonts. A ForEach instance iterates over the array, producing new Text instances that display examples of each SwiftUI Font style provided in the array.
private struct NamedFont: Identifiable {
let name: String
let font: Font
var id: String { name }
}
private let namedFonts: [NamedFont] = [
NamedFont(name: "Large Title", font: .largeTitle),
NamedFont(name: "Title", font: .title),
NamedFont(name: "Headline", font: .headline),
NamedFont(name: "Body", font: .body),
NamedFont(name: "Caption", font: .caption)
]
var body: some View {
ForEach(namedFonts) { namedFont in
Text(namedFont.name)
.font(namedFont.font)
}
}[Image]
Some containers like List or LazyVStack will query the elements within a for each lazily. To obtain maximal performance, ensure that the view created from each element in the collection represents a constant number of views.
For example, the following view uses an if statement which means each element of the collection can represent either 1 or 0 views, a non-constant number.
ForEach(namedFonts) { namedFont in
if namedFont.name.count != 2 {
Text(namedFont.name)
}
}You can make the above view represent a constant number of views by wrapping the condition in a VStack, an HStack, or a ZStack.
ForEach(namedFonts) { namedFont in
VStack {
if namedFont.name.count != 2 {
Text(namedFont.name)
}
}
}When enabling the following launch argument, SwiftUI will log when it encounters a view that produces a non-constant number of views in these containers:
-LogForEachSlowPath YES