Problems pausing UIViewPropertyAnimation

Viewed 493

I am using UIViewPropertyAnimator to make small contentOffset animations.
To keep my view controller lean I have the animation code in the UIScrollView subclass which is to be animated. I originally did my animations in a UIView.animate block, but I noticed that when the view disappears (i.e. another view is pushed on top of the view) the animation jumps to the end, so I am trying to implement a pause in the animation. In addition I wanted to reduce the CPU load through unnecessary animation calls.

var animator: UIViewPropertyAnimator?
...

func showAnimation() {
  ... 
  if animator == nil {
    animator = UIViewPropertyAnimator(duration: duration, curve: .linear, animations: { [unowned self] in
      self.contentOffset = endPoint
    })
    animator?.addCompletion { [unowned self] (position) in
      if position == .end {
        self.afterAnimation()
        print("completion called")
      }
    }
  }
}

func pauseAnimation() {
  if animator?.state == .active {
    animator?.pauseAnimation()
  }
  print("paused animation")
}

The method afterAnimation() just determines if the showAnimation() is to be called again or not.

In my view controller I basically have the following:

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  myScrollView.showAnimation()
}


override func viewWillDisappear(_ animated: Bool) {
  viewWillDisappear(animated)
  myScrollView.pauseAnimation()
}

Now this works well as long as the user does not stay on another screen too long. For example if the user calls up the settings screen (which gets pushed onto the navigation stack) the pause method is called - just as expected. If the user stays in that screen too long, then the animator's completion method is called, even though the animation is not completed. Once the user dismisses the settings screen again the animation is frozen and does not continue.

I also tried working with

animator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: 0, options: .curveLinear, animations: { [unowned self] in
  self.contentOffset = endPoint
  print("starting animation")
}) { [unowned self]  _ in
  self.afterAnimation()
  print("completion called")
}

but the results were the same. After a while the completion block gets called.

How can I best solve this issue? Thanks!

EDIT: Through different print statements I am slowly having the idea that even when the animator gets paused, the animation's internal counter continues and calls the completion block when the animation should be finished.

0 Answers
Related