I am working with a ScrollView and a LazyVStack that can have many rows, sometimes 500 or more. My rows are expandable on tap. Performance of expand/collapse is unacceptable when the number of rows exceeds 100. The more rows, the more performance degrades.
This is the gist of my code:
I created an init function in PlaceView with the following:
What I have noticed is when expanding, every single PlaceView calls init. For 20 or 30 PlaceView rows this is not a problem, but with several hundred views this creates a choppiness in animation and delays the expansion of the detail section.
Is there any workaround for this problem? It does not matter if I use LazyVStack or VStack (which itself is unexpected).
Here is an example project that can easily be modified to highlight the problem: https://github.com/V8tr/ExpandableListSwiftUI
In the above project, simply add the following to PlaceView.swift
This is the gist of my code:
Code Block struct PlaceView: View { /* ... */ var place: Place @Binding expandedPlaceId: Int var content: some View { VStack(alignment: .leading) { Text(place.name) if self.expandedPlaceId.wrappedValue == place.id { VStack(alignment: .leading) { Text(place.city) } } } } }
Code Block struct PlacesListView: View { /*...*/ @State expandedPlaceId = -1 var body: some View { ScrollView { LazyVStack { ForEach(places, id: \.id) { place in PlaceView(place: place, expandedPlaceId: self.$expandedPlaceId) .onTapGesture { self.selectDeselect(place) } .animation(.linear(duration: 0.3)) } } } } }
I created an init function in PlaceView with the following:
Code Block print("calling int for place \(place.id)")
What I have noticed is when expanding, every single PlaceView calls init. For 20 or 30 PlaceView rows this is not a problem, but with several hundred views this creates a choppiness in animation and delays the expansion of the detail section.
Is there any workaround for this problem? It does not matter if I use LazyVStack or VStack (which itself is unexpected).
Here is an example project that can easily be modified to highlight the problem: https://github.com/V8tr/ExpandableListSwiftUI
In the above project, simply add the following to PlaceView.swift
Code Block init(place: Place, isExpanded: Bool) { self.place = place self.isExpanded = isExpanded print("PlaceView init \(self.place.id)") }