Contents

How To Make iOS Animations With UIImageView in Swift


iOS Animations is a huge topic. A great animation can make the difference for a successful application. In this tutorial, we are going to see how to use UIImageView to make amazing animations.

Introduction

When we speak about animations in iOS, we usually think to the static method animate of UIView or transition animations. In addition to this, UIKit provides also the possibility to create animations with an UIImageView using a series of images.

This article is split in two parts:

  • Theoretical: Description of the public interface of UIImageView to create the animations.
  • Practical: A sample app to show how to create an animation using UIImageView.

Happy Reading!

Public Interface

UIImageView exposes some methods and properties to handle the animations:

  • open var animationImages: [UIImage]?

    This array contains the images to show in the animation. By default, it’s nil.

  • open var highlightedAnimationImages: [UIImage]?

    This array contains the images to show in the animation when the view is highlighted. By default, it’s nil.

  • open var animationDuration: TimeInterval

    The time, in seconds, to complete a cycle of images. By default, it’s the number of images * 1/30th of a second.

  • open var animationRepeatCount: Int

    Number of times we want to repeat the animation. 0 means infinite. The default value is 0.

  • open func startAnimating()

    Method to start the animation.

  • open func stopAnimating()

    Method to stop the animation.

  • open var isAnimating: Bool { get }

    Boolean information which indicates if the animation is running.

UIImageView shows the animationImages and highlightedAnimationImages only when the animation is running. If we don’t run the animation, the UIImageView shows the default image set in the property:

1
var image: UIImage?

Example

Now, we are ready to make an application using the UIImageView for the animations.

In this example, we are going to use an UIImageView to make a Chromecast icon animation:

Getting Started

In the next section, we are going to see all the steps to build the sample app. You can download the final project here.

The sample app is very plain. It has two UIKit elements:

  • UIImageView: We’ll use this component to show the Chromecast icon and its animation.
  • UIButton: The action of this button will start the simulated connection and disconnection of a Chromecast device.

Prepare icons

Before starting coding, we need the icons to show. You can find the Chromecast icons set here.

Once we download the icons, we can add them in the project assets with the following names:

Prepare UI

The next step is creating the UI inside the initial view controller of Main.storyboard:

Then, we can link the UI components to two IBOutlet properties inside ViewController:

1
2
@IBOutlet private weak var chromecastImageView: UIImageView!
@IBOutlet private weak var connectButton: UIButton!

Prepare Animation

At this point, we have to prepare the UIImageView for the animation.

In ViewController, we can setup chromecastImageView inside the method viewDidLoad:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
override func viewDidLoad() {
    super.viewDidLoad()

    setupImageViewAnimation()
}
    
private func setupImageViewAnimation() {
    chromecastImageView.animationImages = [#imageLiteral(resourceName: "cast_0"), #imageLiteral(resourceName: "cast_1"), #imageLiteral(resourceName: "cast_2")]
    chromecastImageView.animationDuration = 1
}

With this configuration, we have an UIImageView which is ready to animate the images cast_0, cast_1 and cast_2 in one second.

If you don’t know #imageLiteral, I would suggest you to have a look at this article.

Trigger Animation

The last step is triggering the animation. First of all, we need a property to store the Chromecast state connected/disconnected:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
enum CastState {
    case connected
    case disconnected
}

class ViewController: UIViewController {
    
    private var castState = CastState.disconnected
    
    // ...

Then, we must create a new IBAction for connectButton with the event touch up inside:

1
2
@IBAction private func onConnectButton(_ sender: Any) {
}

Now, we can add the implementation to trigger the Chromecast icon animation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@IBAction private func onConnectButton(_ sender: Any) {
    switch castState {
    case .connected:
        disconnect()
    case .disconnected:
        connect()
    }
}
    
private func connect() {
    // Disables the button to avoid user interaction when the animation is running
    connectButton.isEnabled = false
    
    chromecastImageView.startAnimating()
    
    // Simulates a connection with a delay of 3 seconds
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        self.chromecastImageView.stopAnimating()
        
        // Enables the button to allow user interaction
        self.connectButton.isEnabled = true

        // Updates UI
        self.toggleCastState()
    }
}
    
private func disconnect() {
    // Updates UI
    toggleCastState()
}
    
private func toggleCastState() {
    // Updates current Chromecast state
    castState = castState == .connected ? .disconnected : .connected
    
    // Updates button title
    let buttonTitle = castState == .connected ? "Disconnect" : "Connect"
    connectButton.setTitle(buttonTitle, for: .normal)
    
    // Updates `UIImageView` default image
    let image = castState == .connected ? #imageLiteral(resourceName: "cast_connected") : #imageLiteral(resourceName: "cast_disconnected")
    chromecastImageView.image = image
}

We perform the animation only when we connect a new Chromecast device.

Conclusion

In the sample app, we used the UIImageView for two purposes:

  1. Set the property image to show the current Chromecast state (cast_connected/cast_disconnected).
  2. Run the Chromecast icon animation.

In some scenarios, we may not need the point 1. If we want to use UIImageView only to show an animation, we can assign to the property image an animation like this:

1
2
let images: [UIImage] = [#imageLiteral(resourceName: "cast_0"), #imageLiteral(resourceName: "cast_1"), #imageLiteral(resourceName: "cast_2")]
chromecastImageView.image = UIImage.animatedImage(with: images, duration: 1)

In this way, UIImageView shows an infinite animation automatically. We don’t need to start it manually.

The image for the header comes from Draw with Jazza