How to call scrollViewDidScroll: just like UIScrollView does, but during custom animation?

I have a very large horizontal scrollable UIScrollView that reuses its sub items (moves and updates them when they exit the visible area, much like a UITableView reuses cells). It depends on scrollViewDidScroll: delegate a call that gives me the actual contentOffset, and here I decide when to reuse a particular subview. So far so good.

Sometimes I need to change the contentOffset programmatically, but with custom animation (inertia and return to the end position). I can do this quite easily using basic animation.

The problem is that during custom animation, scrollViewDidScroll: the delegate method is not called -> I have to do it manually so that reuse of subviews works. I tried to call it with a timer starting every 0.02 sec. Now there are two problems:

  • I have to get the UIScrollView contentOffset using the [[_scrollView.layer presentationLayer]]. Origin.x framework because during the animation the regular _scrollView.contentOffset does not change.

    However, the information from presentationLayer is not enough for accurate synchronization - sometimes it's a bit late.

  • The problem is that the new contentOffset is far from the current position. It seems that the UIScrollView inline animation is a CAKeyframeAnimation, and scrollViewDidScroll should be called at the keyframe position. But I canโ€™t get them.

    If I rely on a timer that is not in sync with keyframes, the views are reused in the wrong places, and I don't see them at all during the animation.

Can someone shed some light on how and when exactly the UIScrollView calls scrollViewDidScroll during setContentOffset: X animated: YES? Can I play it without breaking the rules of the appstore?

+6
source share
1 answer

First of all, I would not use NSTimer with a delay of 0.02 seconds - this is not what timers are for. Try using CADisplayLink , it fires once per frame.


In your callback method, you can - if your custom animation is running - run your own physical code and call -setContentOffset: animated: respectively. It even allows you to simplify exponentially what the CA will not allow you.

+4
source

Source: https://habr.com/ru/post/913527/


All Articles