DEV Community

Fazal Shah
Fazal Shah

Posted on

How to Use Lottie Animations in iOS with Swift (2025 Guide)

Lottie is the standard way to ship After Effects animations in iOS apps. It renders animations natively — no WebView, no GIF, no frame-dropping. This guide covers everything from setup to advanced playback control using the official lottie-ios library.


Why Lottie for iOS?

  • Native rendering via Core Animation — no WebView overhead
  • Vector-based — crisp on all screen densities, including ProMotion 120Hz displays
  • Tiny files — a 3-second loading animation is typically under 15KB
  • Full control — play, pause, loop, seek to specific frames programmatically
  • Both UIKit and SwiftUI supported

Step 1: Before You Add the File — Preview It First

Before dropping any Lottie file into Xcode, preview it in IconKing:

  • See exactly how the animation looks (colors, timing, layers)
  • Edit colors to match your iOS app's design system
  • Convert .json → .lottie format (75% smaller file size)
  • Catch broken layers or missing fonts before they cause issues at runtime

No account needed. Drop the file, inspect, adjust, download.


Step 2: Install lottie-ios

Swift Package Manager (recommended)

  1. In Xcode, go to File → Add Package Dependencies
  2. Enter: https://github.com/airbnb/lottie-spm.git
  3. Select Up to Next Major Version from 4.0.0
  4. Click Add Package

CocoaPods

pod 'lottie-ios'
Enter fullscreen mode Exit fullscreen mode

Run:

pod install
Enter fullscreen mode Exit fullscreen mode

Step 3: Add Your Animation File

  1. Drag your .json or .lottie file into your Xcode project
  2. Make sure "Add to targets" is checked for your app target
  3. Verify the file appears in Build Phases → Copy Bundle Resources

Step 4: Basic Usage (UIKit)

import UIKit
import Lottie

class LoadingViewController: UIViewController {

    private var animationView: LottieAnimationView!

    override func viewDidLoad() {
        super.viewDidLoad()

        animationView = LottieAnimationView(name: "loading")
        animationView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        animationView.center = view.center
        animationView.contentMode = .scaleAspectFit
        animationView.loopMode = .loop
        animationView.play()

        view.addSubview(animationView)
    }
}
Enter fullscreen mode Exit fullscreen mode

name: matches the filename without extension (e.g., loading.json → "loading").


Step 5: Basic Usage (SwiftUI)

import SwiftUI
import Lottie

struct LoadingView: View {
    var body: some View {
        LottieView(animation: .named("loading"))
            .playing(loopMode: .loop)
            .frame(width: 200, height: 200)
    }
}
Enter fullscreen mode Exit fullscreen mode

For SwiftUI, use LottieView (added in lottie-ios 4.0).


Loop Modes

// Loop forever
animationView.loopMode = .loop

// Play once and stop
animationView.loopMode = .playOnce

// Ping-pong (forward then backward)
animationView.loopMode = .autoreverse

// Repeat 3 times then stop
animationView.loopMode = .repeat(3)
Enter fullscreen mode Exit fullscreen mode

Playback Control

// Play from current position
animationView.play()

// Play with completion handler
animationView.play { completed in
    if completed {
        print("Animation finished")
    }
}

// Pause
animationView.pause()

// Stop and reset to beginning
animationView.stop()

// Play specific frame range
animationView.play(fromFrame: 0, toFrame: 60, loopMode: .playOnce)
Enter fullscreen mode Exit fullscreen mode

Speed Control

// Half speed
animationView.animationSpeed = 0.5

// Double speed
animationView.animationSpeed = 2.0

// Reverse
animationView.animationSpeed = -1.0
Enter fullscreen mode Exit fullscreen mode

Seek to a Specific Frame

// Jump to frame 30
animationView.currentFrame = 30

// Jump to normalized progress (0.0 to 1.0)
animationView.currentProgress = 0.5
Enter fullscreen mode Exit fullscreen mode

Dynamic Color Replacement

Override colors at runtime without editing the source file:

let colorProvider = ColorValueProvider(UIColor.systemBlue.lottieColorValue)
animationView.setValueProvider(colorProvider, keypath: AnimationKeypath(keypath: "**.Fill 1.Color"))
Enter fullscreen mode Exit fullscreen mode

The keypath uses the layer/property structure from After Effects. To find the right keypath, open the .json file and inspect the layers — or use IconKing to browse the layer structure before writing code.


Using dotLottie (.lottie) Format

dotLottie files are ~75% smaller than .json. For lottie-ios 4.4+:

// Load from bundle
let animation = LottieAnimation.named("loading") // works for both .json and .lottie

// The library detects the format automatically
animationView = LottieAnimationView(animation: animation)
Enter fullscreen mode Exit fullscreen mode

To convert your .json to .lottie, use IconKing — drop the file, click convert, download. The converted file will be significantly smaller, which matters for app bundle size.


Loading from a URL

LottieAnimation.loadedFrom(url: URL(string: "https://example.com/animation.json")!) { animation in
    guard let animation = animation else { return }
    DispatchQueue.main.async {
        self.animationView.animation = animation
        self.animationView.play()
    }
}
Enter fullscreen mode Exit fullscreen mode

Performance Tips

1. Stop animations when not visible

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    animationView.stop()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    animationView.play()
}
Enter fullscreen mode Exit fullscreen mode

2. Use .lottie format over .json

Smaller bundle size, faster loading. Convert at IconKing.

3. Use renderingEngine: .coreAnimation for complex animations

let animationView = LottieAnimationView(
    name: "complex-animation",
    configuration: LottieConfiguration(renderingEngine: .coreAnimation)
)
Enter fullscreen mode Exit fullscreen mode

Core Animation rendering uses the GPU and is significantly faster for animations with many layers.


Complete Example: Splash Screen

import UIKit
import Lottie

class SplashViewController: UIViewController {

    private var animationView: LottieAnimationView!
    var onComplete: (() -> Void)?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupAnimation()
    }

    private func setupAnimation() {
        animationView = LottieAnimationView(name: "splash")
        animationView.translatesAutoresizingMaskIntoConstraints = false
        animationView.contentMode = .scaleAspectFit
        animationView.loopMode = .playOnce

        view.addSubview(animationView)

        NSLayoutConstraint.activate([
            animationView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            animationView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            animationView.widthAnchor.constraint(equalToConstant: 250),
            animationView.heightAnchor.constraint(equalToConstant: 250)
        ])

        animationView.play { [weak self] _ in
            self?.onComplete?()
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Common Issues

"Animation not found" crash

The file isn't in the bundle. Check:

  1. The file is added to Build Phases → Copy Bundle Resources
  2. The filename matches exactly (case-sensitive on device)

Animation looks different on device vs. preview

Preview in IconKing first. If it looks correct there, the issue is likely contentMode or a rendering engine mismatch. Try switching between .automatic and .coreAnimation rendering.

Colors look wrong

lottie-ios 4.x changed how some color modes render vs. the older library. Use setValueProvider to override colors at runtime rather than hardcoding them in the JSON.


Finding Lottie Files for iOS

  • LottieFiles — large free library
  • IconKing — preview any file, edit colors to match your app's palette, convert between .json and .lottie formats before adding to Xcode

Always preview before adding to your project. A file that looks great on desktop might have clipped bounds or unexpected behavior at iOS screen sizes — IconKing lets you catch this in the browser before it becomes an Xcode problem.


Summary

  1. Install lottie-ios via SPM or CocoaPods
  2. Add your animation file to the Xcode bundle
  3. Use LottieAnimationView (UIKit) or LottieView (SwiftUI)
  4. Set loopMode, call .play()
  5. Override colors with setValueProvider if needed
  6. Convert to .lottie at IconKing for smaller app size
  7. Use Core Animation rendering engine for complex animations

Top comments (0)