Group Group Group Group Group Group Group Group Group

Auto-scrolling of UIScrollView (animation)

Hi there,

I wonder how I can make a ScrollView auto-scroll at a certain speed by clicking a button. I’m making a kind of song/chord book so I’d like a song text to slowly scroll up while you’re playing a musical instrument and singing along.

I suppose I should animate the content area position in the y-axis and set the time to determine the speed of the animation. But how exactly can I do it?

Thanks.

After asking here, I continued to experiment and found that the following IBAction on the button did the trick:

@IBAction func hitBtn(_ sender: Any) {

    UIView.animate(withDuration: 10, animations: {
        
    self.scrollView.contentOffset = CGPoint(x: 0, y: 1000)
    })
}

Are there better options for the task?

And I have a few more questions:

  1. Let’s say I have a Play button which triggers the auto-scrolling animation. How can I stop the animation? Which function stops it?
  2. Is there any way how a user can interact with the scroll view while it’s moving during the animation? By default, when the animation starts, the scroll view stops reacting to my finger slides.

You can stop animations with something like

scrollView.layer.removeAllAnimations()

This might be a case where using a timer instead of UIView.animate would be useful. It would avoid blocking user interaction while the animation is running. In particular, you could use CADisplayLink, which is a timer that synchronizes with the display refresh rate.

There is tutorial for that here:
https://www.raywenderlich.com/113835-ios-timer-tutorial#

The CADisplayLink version is at the end. It starts using a regular timer for the balloon effect, and then replaces it with CADisplayLink.

Instead of making an animation, you setup a method to calculate the appropriate increment of the contentOffset, and then have CADisplayLink call it for each frame. If you use the CACurrentMediaTime to track elapsed time, as shown in the tutorial, you can calculate the offset precisely each time, even if the time interval varies.

With user interaction enabled, you could then just stop the timer when the user touches the view, and they would be able to scroll manually again.

Thank you for the reply, I’ll give it a try =)