Post

Replies

Boosts

Views

Activity

SwiftUI ScrollView LazyVStack Performance
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: 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) 								} 						} 				} 		} } 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: 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 init(place: Place, isExpanded: Bool) {         self.place = place         self.isExpanded = isExpanded         print("PlaceView init \(self.place.id)") }
2
1
5.2k
May ’23
SwiftUI ScrollView LazyVStack Performance
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: 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) 								} 						} 				} 		} } 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: 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 init(place: Place, isExpanded: Bool) {         self.place = place         self.isExpanded = isExpanded         print("PlaceView init \(self.place.id)") }
Replies
2
Boosts
1
Views
5.2k
Activity
May ’23