切换UIViewController时UIImageView旋转动画加速问题求助
Hey there! Let's break down why your UIImageView's rotation animation is speeding up when switching between view controllers, and walk through how to fix it.
What's Causing the Speed-Up?
The most likely culprit is animation stacking. Every time your view controller appears (viewDidAppear), you're adding a new rotation animation to the image view—but if the previous animation wasn't fully removed (even if you called stopAnimation), multiple animations end up running at the same time. Each additional animation adds to the rotation speed, making it look like it's accelerating with every switch.
Step-by-Step Solutions
1. Fix Your stopAnimation Function
First, make sure you're completely removing all animations from the image view's layer, not just pausing or hiding it. Here's the correct implementation:
func stopAnimation() { // Remove all active animations from the image view's layer imageView.layer.removeAllAnimations() // Optional: Reset the transform to avoid leftover rotation state imageView.transform = .identity }
2. Ensure Clean Animation Starts
Before starting a new animation in viewDidAppear, always call stopAnimation first to clear any residual animations. This prevents stacking:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // Stop any existing animations before starting a new one stopAnimation() startAnimation() }
3. Use CABasicAnimation for More Control (Recommended)
Instead of relying on UIView.animate, using CABasicAnimation gives you better control over the animation's lifecycle, including the ability to target specific animations by a key. This avoids accidentally removing other animations if you add more later.
Here's a robust infinite rotation implementation:
func startAnimation() { // Clear old animations first stopAnimation() let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z") rotationAnimation.toValue = CGFloat.pi * 2.0 // Rotate 360 degrees rotationAnimation.duration = 1.0 // Adjust this to control rotation speed rotationAnimation.repeatCount = .infinity // Infinite loop rotationAnimation.isRemovedOnCompletion = false // Keep the final rotation state rotationAnimation.fillMode = .forwards // Add the animation with a unique key so we can target it later if needed imageView.layer.add(rotationAnimation, forKey: "infiniteRotation") }
4. Verify viewWillDisappear Call
Double-check that stopAnimation is actually being called in viewWillDisappear. Sometimes if you're using navigation controllers or custom transitions, you might need to use viewDidDisappear instead—but viewWillDisappear should work for most cases:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) stopAnimation() }
Why This Works
By removing all existing animations before starting a new one, you ensure only one rotation animation runs at a time. Using CABasicAnimation also avoids the subtle issues that can come with UIView.animate's block-based approach, where repeated calls can leave residual transform states or stacked animations.
内容的提问来源于stack exchange,提问作者Dani

