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
}
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 a UICollectionViewCell
, but there is not a 1:1 correspondence between the number of NameTextView
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.