The below list view loads 1000 rows and I see 1000 NameTextView
being created.
But with reusability we should be seeing very few NameTextView
. Is there a way to optimize the code and number of rows that will be created.
I am doing similar thing as posted in Answer for question Reusability support in List in SwiftUI
import SwiftUI
struct ListContentView: View {
var items = createList()
var body: some View {
List(items) { element in
NameTextView(name: element.name)
}
.listStyle(PlainListStyle())
}
}
struct NameTextView: View {
var name: String
var body: some View {
Text(name)
}
}
#Preview {
ListContentView()
}
struct ListElement: Identifiable {
var id = UUID().uuidString
var name: String
}
func createList() -> [ListElement] {
var items: [ListElement] = []
for i in 0..<1000 {
items.append(ListElement(name: "Name (i)"))
}
return items
}
2
Answers
SwiftUI views make use of UIKit components under the covers, but that doesn’t mean that SwiftUI views are just direct wrappers around UIKit components.
In the case of a
List
you have some SwiftUI view (NameTextView
in your case) being shown in aUICollectionViewCell
, but there is not a 1:1 correspondence between the number ofNameTextView
s and the number of underlying cells that are needed.SwiftUI views are immutable structs and so a unique struct instance is required for each
NameTextView
– In your case, a total of 10,000 will be required, but only if you scrolled to the end of the list; additional views are created as you scroll and they need to be shown.These are displayed on a number of
UICollectionViewCells
– You don’t have direct visibility of the creation or reuse of these cells, but I would expect that there would be about n+4 of them for a list with n visible rows (the extra cells allow for off-screen cells in preparation for scrolling).So, the short answer is you cannot make SwiftUI views reusable because SwiftUI views are immutable structs. Every time there is any change in a SwiftUI view, a new view is created to replace the old one.
The underlying collection view cells are re-used.
❌ It seems like you did an incorrect measurement because
✅
List
is reusable in SwiftUI!Whether its backed by
UICollectionView
for newer SwiftUI versions orUITableView
for older versions (or the AppKit counterparts for the macOS),List
always reuses its items (not the parent hosting view itself)Here is more information (for the SwiftUI 1 but the latest does the same with collection view)
You can see there are only a few (reusable) items.
⚠️ The image is cropped to pay attention to the focused area but as you can see, obviously there is not 1000 items.