Swift
UIImageView
Animation
Rotate
iOS

animate rotation UIImageView in swift

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Rotating a UIImageView is a common pattern for loaders, status icons, and lightweight interaction feedback in iOS apps. The right implementation depends on whether you need a one-off turn, a continuous spinner, or a rotation that can pause and resume cleanly. In practice, UIView animation works well for finite transforms, while Core Animation is better for indefinite spinning.

Finite Rotation with UIView.animate

If you only need to rotate once or a small number of times, animating the view transform is the simplest approach.

swift
1import UIKit
2
3func rotateOnce(_ imageView: UIImageView) {
4    UIView.animate(
5        withDuration: 0.35,
6        delay: 0,
7        options: [.curveEaseInOut],
8        animations: {
9            imageView.transform = imageView.transform.rotated(by: .pi)
10        }
11    )
12}

This is good for:

  • Expanding disclosure arrows.
  • Toggling icons between states.
  • Simple rotation effects paired with other layout changes.

Because it modifies the transform directly, it composes naturally with ordinary view animations.

Continuous Spinning with Core Animation

For loader-style indefinite rotation, Core Animation is usually the better tool because it runs efficiently and avoids repeatedly updating the transform on the main thread.

swift
1import UIKit
2
3func startSpinning(_ imageView: UIImageView) {
4    let key = "rotation"
5
6    if imageView.layer.animation(forKey: key) != nil {
7        return
8    }
9
10    let spin = CABasicAnimation(keyPath: "transform.rotation.z")
11    spin.fromValue = 0.0
12    spin.toValue = Double.pi * 2.0
13    spin.duration = 1.0
14    spin.repeatCount = .infinity
15    spin.timingFunction = CAMediaTimingFunction(name: .linear)
16
17    imageView.layer.add(spin, forKey: key)
18}
19
20func stopSpinning(_ imageView: UIImageView) {
21    imageView.layer.removeAnimation(forKey: "rotation")
22}

This is the standard pattern for a smooth infinite spinner.

Avoid Snap-Back When Stopping

One visual issue with Core Animation is that the view may jump back to its original orientation when you remove the animation. If you want the image to stop exactly where it is, copy the current presentation-layer rotation into the view transform before removing the animation.

swift
1import UIKit
2
3func stopSpinningSmoothly(_ imageView: UIImageView) {
4    if let presentation = imageView.layer.presentation(),
5       let angle = presentation.value(forKeyPath: "transform.rotation.z") as? CGFloat {
6        imageView.transform = CGAffineTransform(rotationAngle: angle)
7    }
8
9    imageView.layer.removeAnimation(forKey: "rotation")
10}

That keeps the final frame visually stable instead of snapping to zero rotation.

Lifecycle and Visibility

If the image is part of a loading indicator, animation should be tied to visibility and actual work state. Starting animations too early or leaving them running off-screen wastes resources and can produce confusing UI state.

Typical pattern:

swift
1final class LoadingViewController: UIViewController {
2    @IBOutlet private weak var spinnerImageView: UIImageView!
3
4    override func viewDidAppear(_ animated: Bool) {
5        super.viewDidAppear(animated)
6        startSpinning(spinnerImageView)
7    }
8
9    override func viewWillDisappear(_ animated: Bool) {
10        super.viewWillDisappear(animated)
11        stopSpinning(spinnerImageView)
12    }
13}

If animation is tied to a network request instead, start and stop it from the request lifecycle rather than the screen lifecycle.

Auto Layout and Rendering Considerations

Rotation does not change constraints. Auto Layout still lays out the untransformed bounds, and the visual rotation happens afterward. That is usually fine, but clipped edges can appear if the container is too tight or clipsToBounds is enabled on a parent view.

Also check:

  • 'contentMode of the image view.'
  • Whether the image has enough padding around edges.
  • Whether several rotations are being applied cumulatively.

Repeated transform changes without resetting state can make the final orientation hard to reason about.

Accessibility and Motion Settings

Continuous spinning can be distracting for users who prefer reduced motion. Respect system accessibility settings where appropriate.

swift
1if UIAccessibility.isReduceMotionEnabled {
2    // Use a static icon or subtle fade instead of spinning.
3} else {
4    startSpinning(imageView)
5}

That is especially important for long-lived loading indicators or decorative animations.

Common Pitfalls

  • Using repeated timer-based transform updates for an infinite spinner. Fix by using Core Animation instead.
  • Re-adding the same animation every time state changes. Fix by guarding with an animation key check.
  • Removing an infinite animation and accepting a visible snap-back. Fix by copying the presentation-layer angle before removal.
  • Starting animation before the view is actually visible. Fix by tying animation to a clear lifecycle or loading-state boundary.
  • Ignoring reduced-motion accessibility settings. Fix by providing a non-rotating fallback for users who disable motion-heavy effects.

Summary

  • Use UIView.animate for simple finite rotations.
  • Use CABasicAnimation for efficient continuous spinning.
  • Preserve the current presentation angle if you need a smooth stop.
  • Tie rotation lifecycle to visibility or request state, not arbitrary callbacks.
  • Respect accessibility motion settings and avoid unnecessary animation churn.

Course illustration
Course illustration

All Rights Reserved.