Reputation: 91681
I have a very simple animation block which performs the following animation:
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:
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:
options: UIViewAnimationOptions.beginFromCurrentState
. It does the same exact behavior.0
second animation that changes the constant to 0
, and calls superview!.layoutIfNeeded
.Other notes:
transform
from CGAffineTransform.identity
to CGAffineTransform(scaleX: 0.5, y: 0.5)
, I get the same behavior where it'll grow to 120 points.backgroundColor = UIColor(white: 0, alpha: 0.5)
to backgroundColor = UIColor(white: 0, alpha: 0)
, then I get correct behavior (i.e. each time I tap the button, the color resets to 0.5
gray at most. It never gets to black.Upvotes: 4
Views: 134
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
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:
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