Search code examples
iosswiftlistswiftui-list

Make SwiftUI List view reusable


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
}



Solution

  • 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 NameTextViews 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.