I know SwiftUI does not support currently regular for loops but instead provide something called ForEach but what is the difference between that and a List?
3 Answers
ForEach
is a view that lets you pass a collection of data to its initializer and then creates multiple "subviews" from the closure you provide. It doesn't have any semantics on how the views will be arranged.Example:
ForEach(1..<5) { row in Text("Row \(row)") }
will create the equivalent off
Text("Row 1") Text("Row 2") Text("Row 3") Text("Row 4")
wrapped in a single container view.
List
is a view that can compose multiple views together, but not necessarily views of the same type. You can simply add multiple views without any loop.Example 1:
List { Image("avatar") Text("Title") Button(action: { print("Button tapped!") }) { Text("Energize!") } }
As a convenience, the
List
initializer allows you to use it just like theForEach
view in case you want to have a list consisting of a single cell type only.Example 2:
List(1..<5) { row in Text("Row \(row)") }
A list has a special appearance, depending on the platform. For example, on iOS a list will appear as a table view and insert separator lines between its vertically stacked views.
You can use
ForEach
views insideList
views to have both dynamic and static content – a very powerful feature of SwiftUI.Example 3:
List { Text("Food") ForEach(meals) { meal in Text(meal.name) } Text("Drinks") ForEach(drinks) { drink in Text(drink.name) } }

- 15,816
- 8
- 59
- 117
-
9Nice answer. Some tweaks: 1. You don’t need most of those `return`s ([SE-255](https://github.com/apple/swift-evolution/blob/master/proposals/0255-omit-return.md), yo). And if you’re just passing a string to `Text(...)` there’s no need to wrap it in string interpolation — SwiftUI automatically makes programmatic Strings non localized and localizes literals and interpolation. – rickster Jun 14 '19 at 06:28
-
1
-
5Can you elaborate on the performance? Which one does reusing cells better? For a continuous feed kind of data set, which one should be preferred? – imthath Feb 02 '20 at 09:00
-
I (sadly) realized that a ForEach (without List) can't manage insert, update and delete animations. Of couse you can add an animation and transition modifier to your rows, but sadly they also get fired when you just update a row (this leads to an insert animation when you e.g. just updated the text at one index). In a list this also triggers as "new row" (onAppear() gets triggered) but the list itself manages to suppress animation ... – orschaef Apr 28 '20 at 16:42
-
"Example" doesn't work anymore in 2021, pls change to `ForEach(1..<10) { row in` – Richard Topchii Dec 15 '21 at 10:48
-
SwiftUI List vs ForEach
List
:
- mixed content(also allows to work with collection)
- scrollable
- uses reusing cell pattern (efficient)
ForEach
:
- works only with a collection
List
+ ForEach
= super feature. In this case, for example, List
uses reusing cell pattern for every view from ForEach
. Also you are able to use onMove
, onDelete
...

- 29,217
- 8
- 193
- 205
Simple explanation:
- List behaves like a UIScrollView (an arbitrarily long scrollable view of views)
- ForEach behaves kind of like a UITableView (where each of the elements gets a cell view, and it's also scrollable)

- 562
- 5
- 9
-
4This is a useful way to equate it back to UIKit, for users coming from the old way. Minor quibble, but I think it's the other way around: List behaves like UITableView, and ForEach behaves like UIScrollView. I tested both, and ForEach by itself just displays repeating Text views, whereas List shows cells with borders. – James Toomey Apr 27 '22 at 18:17
-
1It's a good answer though. It helped me since I'm used to the UIKit way. – James Toomey Apr 27 '22 at 18:29