A Lottie-driven UI architecture for macOS/iOS applications
I’ve been fascinated by animations from the start of my software development career. When I started writing macOS applications using Cocoa, one of the first things I did was an animated button. Just an ordinary button. With some ripples when you click it. It looked like this:
And boy it was hard. Creating animations from scratch in code was one of the most unintuitive things I’ve ever done. It’s like these boxes with gloves for working with radioactive materials. You can definitely do things, but it will hurt your brain.
Can you imagine what the animation would look like if I changed the second key time value from 19 to 22? Keep in mind that EaseInEaseOut is used ;)
After several years of raising my pain threshold, I heard about the Lottie framework from our frontend developers. And this has changed my life. For those who are unfamiliar with Lottie, it is a framework that magically converts an animation from Adobe After Effects to a bunch of native CALayers.
We started using it for simple video-like animations throughout the project. Little spinner here, cute preload there.
But why should we stop at preloaders? Because Lottie was designed for it and old project was already pretty done. And it seemed like it would be a long time until my dreams of a painless UI animation could come true. Lottie-driven UI…
But finally, yes the time has come! Clario! The new project, full of glorious animations for every bit of UI. Yey! And a very little time for development. Yey…
So, what we faced with:
Wow, it was just 15 seconds of animations and approximately a month for development =( But how cool would it be if we just import this animation into our product? It has a simple linear flow and no window resizing is expected for the nearest time.
In order to add controls we need to modify Lottie a little bit. We added an observer protocol for every layer in hierarchy. How this works? You can address every part of an animation by its unique path. For example, a blue login button:
Its path is MainComp/2.5/LoginShape. This is similar to the file system, but instead of folders you have After Effects compositions. Every composition has unique properties which can be used for all kinds of workflows. We used just plain CALayer for basic properties because everything else will be rendered by Lottie. (And shape layers in Lottie are weird, as even basic properties require fake container layer)
And now we can observe properties such as `frame`, `opacity`, and `hidden`. This set allows us to use Cocoa views on top of Lottie layers. Buttons, text fields, even scroll views. We created a framework with essential UI elements and a sample project. You can grab it on https://github.com/clario-tech/LottieUI. As a fan of Interface Builder, I also added ViewController which can automatically bind all content to animation. Just drop some view, set keypath and view controller will do everything else. But for adepts of UI in code — there are methods too.
In the first iteration, our buttons were transparent and even click animations were in Lottie. But it was too complicated and unnatural. In the next iteration, we used native NSButton or CompositeButton. CompositeButton is the next level of LottieUI, because it is a button with an animation in it. Whenever you click on this button, it plays its own small animation. Isn’t it neat?
The next step is to mark an animation in After Effects. A new marker is put wherever the animation should be stopped. Every marker has a unique name and the animation can be played from one marker to another. As i mentioned before, we have click animation so we used 3 times more markers than needed =)
You can add a new marker by pressing Shift-6 (or any other digit). All that remains is to export a JSON file and write some business logic. Our logic for this screen is very straightforward.
Designing apps this way eliminates pretty much all the code for appearance and animations. Most of the design preferences in AE are much more sophisticated than in Interface Builder. Also, we can relieve developers of headaches with design changes. You simply need to take the AE file from your designer and export it. As a good practice we are adding AE files to git. And never changing JSON files manually. This way you can export AE files at any time. But it is not ideal for merge requests and merge conflicts as you will never understand what has changed in those files. Better AE files support in git will be great not only for LottieUI, but also for motion designers as they can start using git for their purposes.
So… it’s done. A pretty welcome screen full of animations in just a week. It could be. Unfortunately, it was more than a week =( Original Lottie hadn’t support for videos and effects. And texts were higher than needed and pixelated. It was a disaster. Our fork of Lottie looked like Frankenstein back then. But after weeks of fixes and changes it wasn’t too bad.
No screen recording of the result here. It is the same as on the video. This is the whole point ;)
Pixel perfect UI with no misinterpretation from developers. Forget about misplaced text fields or wrong color. All design elements were as the designer made them. And fixing Lottie is never a bad idea, because it is an investment in the future. It doesn’t matter how many controls, transitions and effects are on every screen. It’s just a matter of one click to export. 3D? No big deal. Fancy blurring? Also easy. Every change to an animation is very obvious and intuitive.
As time went on, our project grew bigger and bigger. More screens and more new logic. It became obvious that to maintain the project, developers should know After Effects basics. Not every sane developer will stop coding and bury themself in AE layers. This leads to a fragmentation. Many screens were objectively simpler to do in Interface Builder. And even great candidates for LottieUI are implemented using familiar instruments. The same for Lottie. It is pretty hard to fix some bugs in an open source project. Especially if a new release tomorrow.
You can’t do a similar screen in LottieUI at the moment.
With expressions, you will be able to implement whatever screen you want. Maybe it will be even simpler than using Swift. We’ll never know if we don’t try.
To sum up: LottieUI is a great way to create simple linear flows. It also can provide a painless solution for enriching your UI with animations. But it is not yet a silver bullet for future UI.
- Screen design can be imported as a single file;
- Animation properties are very intuitive;
- Improved speed of development time.
- Lack of customization and dynamizm(autolayout, localization, etc.);
- Requirement to learn a new tool, steep learning curve;
- Bugs in Lottie.
You can check the Clario macOS app to touch LottieUI in production. Can you spot which screens are native and which are not? =)