Building a bidirectional, infinitely scrolling list using ScrollView - challenges and potential solutions

I have been banging my head against this problem for a bit now.

I am trying to build a bidirectional, infinitely scrolling list that implements these core requirements:

  1. Loads data up/down on the fly as the user scrolls
  2. Preserves scroll velocity as the list is updated
  3. Restores the scroll to the exact visual location after data has changed
  4. Ensures no flicker when restoring scroll position - the user cannot know the list has updated and should continue scrolling as normal

Because LazyVStack does not play well with animations, I am opting to go with VStack and am implementing my own sliding window for data. This means that data can be removed as well as added, and a simple application of a height delta is not enough when restoring position.

So far I have tried many things:

  • Relying on ScrollPosition - simply does not work by itself as described (swift UI trying to keep the position stable with ID's)
  • Relying on ScrollPosition.scrollTo - only kind of works with ID, no way to restore position with pixel perfect accuracy
  • Intercepting the UIKit scrollView instance, using it to record and access the top row's position, mutating data and then queuing a scroll restoration using CATransaction.setCompletionBlock - this is the closest I've come, and it satisfies the top 3 requirements but sometimes I get a flicker on slightly heavier lists

What I would really like, is a way of using ScrollView and granularly hooking into the lifecycle of the view after layout, and just before draw. At this point I would update the relevant scroll positions, and allow draw to continue. Is this possible? My knowledge is very limited at this point, but I believe I may be able to achieve something of the sort by swizzling layerWillDraw? Does this make sense, and is it prudent?

In general, I'm very interesting in hearing what people have to say about the above, as well as this problem in general.

  • Loads data up/down on the fly as the user scrolls
  • Preserves scroll velocity as the list is updated

Those may be conflicting requirements, depending where you load data from.

If it is from the network, you don't control the response time. Hence, how do you expect to keep the same scrolling velocity, whatever solution ? Unless you preload data, but you say you want to load 'on the fly'.

Building a bidirectional, infinitely scrolling list using ScrollView - challenges and potential solutions
 
 
Q