Tech

Easy iOS progress animation with Lottie

by Mar 12, 2019

Anyone who ever tried to create animations using Core Animation iOS framework knows that it requires a lot of effort and time to create even a simple animation. Things become even more complicated when you want to create something more impressive.

One of our designers, Magda Habarta, created a nice Skyrise loader animation demo project. It was prepared for easy usage with web applications, but as a mobile developer I’ve started to think what we could do to use this animation on mobiles with less effort and without needing to create it from scratch. The answer to this is to use a Lottie library.

What is Lottie?

Lottie is an open source animation framework created by the Airbnb team. It uses animations saved in JSON files which are later processed by the framework internally and rendered on the view. Lottie can be used on iOS, Android, Web, React Native and some other platforms. Animations are exported to the JSON format using Adobe After Effects with a Bodymovin plugin. In this article I will focus on the usage of the animation itself. You can read more about the exporting process, preparing the animation, and animation capabilities in the Lottie docs.

How to use it?

Basic usage is very simple. All you need to do is to add a SDK to your project, copy the file with the animation to the project directory, and type in just four lines of code to make the animation work.

Installation using CocoaPods

pod lottie-ios

Adding animation to view

let loaderAnimationView = LOTAnimationView(name: "skyrise-loader")
view.addSubview(loaderAnimationView)
loaderAnimationView.loopAnimation = true
loaderAnimationView.play()

Run

Yeah, it was simple BUT… How to use this animation as a loader or progress indicator?

For the purpose of this article, I’ve prepared a simple example application that allows you to download any image from a given URL with progress monitoring by using URLSessionDownloadDelegate methods. The view contains UIImageView, two LOTAnimationView’s for presenting animations, and a button for starting the download process.

The animation view on the left side is configured as a loader. Basically, the only thing that is needed to use it is to start playing the animation (using play() method) when the download starts and end it (using pause() or stop() methods) when the download is complete, and animation looping must be enabled by setting loopAnimation to true. It works just like many other loaders which you have probably been using in your apps. Lottie has some configuration options for animations like animationSpeed or autoReverseAnimation which could be used to customize our animation.

There’s one thing that could improve your progress animation which I’ve applied for this particular example. Let’s say that the download will complete when the loader animation will be halfway through its progress. If we will just call stop(), the animation will be cut off. To prevent that, you could actually pause the animation when the download completes and let it animate to the end, remembering to disable looping and enable it again when the animation completes. See the code snippet below.

self?.loaderAnimationView.pause()
self?.loaderAnimationView.loopAnimation = false
self?.loaderAnimationView.play(toProgress: 1) { (_) in
    self?.loaderAnimationView.loopAnimation = true
 }

Let’s smoothly move to the second usage of our animation – as a progress indicator. Using animation view as a progress indicator is even simpler. The only thing that you need to do is update the animationProgress property of the animated view. The value for that property is calculated by dividing totalBytesWritten by totalBytesExpectedToWrite which comes from the didWriteData method from URLSessionDownloadDelegate. Progress could also be very easily calculated to a percent value, which in this case is printed to the console. See the example below.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    let progress = CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite)
    let percentValue = ((progress * 100) * 10).rounded() / 10
    print("\(percentValue)%")
    progressAnimationView.animationProgress = progress
}

Finally, below you can see how everything works together in the download process. When the download completes, UIImageView is updated with the downloaded image and all animations are stopped.

Useful resources

There’s a nice web page called https://www.lottiefiles.com/ which contains many animation examples uploaded by the community. It’s a good source to check if you want to try Lottie and see what can be done using it. Lottie even has its own preview applications on Android and iOS which could be used to preview animations. Below you can find some other useful links:

You can find the source code on our GitHub – https://github.com/bt-skyrise/lottie-blog-post

I hope that you enjoyed this article. You should definitely try Lottie in your own project. If you have any questions, feel free to ask in the comments section below. See you! :)

Ready to create better software?

We are constantly working on new interesting projects.

Maybe yours will be one of them?