Senseful
Senseful

Reputation: 91681

iOS animation doesn't reset when replayed repeatedly

I have a very simple animation block which performs the following animation:

enter image description here
(tap the image if the animation doesn't play)

func didTapButton() {
  // reset the animation to 0
  centerYConstraint.constant = 0
  superview!.layoutIfNeeded()

  UIView.animate(
    withDuration: 1,
    animations: {
      // animate the view downwards 30 points
      self.centerYConstraint.constant = 30
      self.superview!.layoutIfNeeded()
  })
}

Everything is great when I play the animation by itself. It resets to position 0, then animates 30 points.

The problem is when the user taps the button multiple times quickly (i.e. during the middle of an ongoing animation). Each time the user taps the button, I would expect it to reset to position 0, then animate downwards 30 points. Instead, I get this behavior:

enter image description here
(tap the image if the animation doesn't play)

It's clearly traveling well over 30 points. (Closer to 120 points.)

Why is this happening, and how can I "reset" the animation properly so that it only at most travels 30 points?

Things that I have tried that didn't work:

Other notes:

Upvotes: 4

Views: 134

Answers (2)

Rob
Rob

Reputation: 437552

I can reproduce the behavior you describe. But if I call removeAllAnimations() on the layer of the view that is moving, the problem goes away.

@IBAction func didTapButton(_ sender: Any) {
    animatedView.layer.removeAllAnimations()

    centerYConstraint.constant = 0
    view.layoutIfNeeded()

    centerYConstraint.constant = 30
    UIView.animate(withDuration: 2) {
        self.view.layoutIfNeeded()
    }
}

Note, I'm not removing the animation from the superview (because that still manifests the behavior you describe), but rather of the view that is moving.

Upvotes: 3

Senseful
Senseful

Reputation: 91681

So far, the only solution I found is to recreate the view rather than trying to reset the existing one.

This gives me the exact behavior I was looking for:

enter image description here
(tap the image if the animation doesn't play)

It's unfortunate that you need to remove the old view and create a new one, but that's the only workaround I have found.

Upvotes: 1

Related Questions