dotLottie iOS Player Usage Guide
Comprehensive guide for using the dotLottie iOS player. Covers DotLottiePlayerView (SwiftUI), DotLottiePlayerUIView (UIKit/AppKit), playback control, event handling, layout, markers, multi-animation, theming, and slots.
dotLottie iOS Player Usage Guide
This guide shows you how to load animations, control playback, and handle events using the dotLottie iOS player. The player provides three approaches:
DotLottiePlayerView— Declarative SwiftUI view with modifier API (recommended for SwiftUI).DotLottiePlayerUIView— UIKit/AppKit view with property-based API (recommended for UIKit).DotLottieAnimation— Lower-level view model used with.view().
SwiftUI with DotLottiePlayerView
DotLottiePlayerView is the recommended way to display animations in SwiftUI. It uses a builder-pattern modifier API.
Basic usage
import SwiftUI
import DotLottie
struct ContentView: View {
var body: some View {
DotLottiePlayerView(animation: DotLottieAnimation(
fileName: "animation",
config: AnimationConfig(autoplay: true, loop: true)
))
.looping()
.playing()
.frame(width: 300, height: 300)
}
}Async loading with placeholder
Load an animation from a URL with a placeholder shown during loading:
struct AsyncAnimationView: View {
var body: some View {
DotLottiePlayerView({
try await DotLottieAnimation(
webURL: "https://example.com/animation.lottie",
config: AnimationConfig(autoplay: true, loop: true)
)
}, placeholder: {
ProgressView()
})
.looping()
.playing()
.frame(width: 300, height: 300)
}
}Controlling playback with modifiers
DotLottiePlayerView(animation: animation)
.playbackMode(.playing) // or .paused
.loopMode(.loop) // or .playOnce
.animationSpeed(2.0) // double speed
.mode(.reverse) // forward, reverse, bounce, bounceReverse
.useFrameInterpolation(true) // smooth playback at slow speeds
.segments((0, 60)) // play frames 0–60
.currentFrame(30) // seek to frame 30
.animationDidLoad {
print("Animation loaded!")
}Reloading an animation
Use reloadAnimationTrigger with a state variable to trigger a reload:
@State private var reloadTrigger = false
DotLottiePlayerView(animation: animation)
.reloadAnimationTrigger(reloadTrigger, showPlaceholder: true)
Button("Reload") {
reloadTrigger.toggle()
}UIKit with DotLottiePlayerUIView
DotLottiePlayerUIView is the recommended way to display animations in UIKit. It provides convenience initializers and a property-based API.
Basic usage
import UIKit
import DotLottie
class ViewController: UIViewController {
var playerView: DotLottiePlayerUIView!
override func viewDidLoad() {
super.viewDidLoad()
playerView = DotLottiePlayerUIView(
name: "animation",
config: AnimationConfig(autoplay: true, loop: true)
)
playerView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
view.addSubview(playerView)
}
}Loading from different sources
// From a file path
let player = DotLottiePlayerUIView(
filePath: "/path/to/animation.lottie",
config: AnimationConfig(autoplay: true, loop: true)
)
// From a URL
let player = DotLottiePlayerUIView(
url: URL(string: "https://example.com/animation.lottie")!,
config: AnimationConfig(autoplay: true, loop: true)
)
// From a JSON string
let player = DotLottiePlayerUIView(
animationData: jsonString,
config: AnimationConfig(autoplay: true, loop: true)
)
// From raw .lottie Data
let player = DotLottiePlayerUIView(
dotLottieData: data,
config: AnimationConfig(autoplay: true, loop: true)
)Controlling playback via properties
playerView.loopMode = .loop // .playOnce or .loop
playerView.animationSpeed = 1.5 // speed multiplier
playerView.mode = .reverse // forward, reverse, bounce, bounceReverse
playerView.useFrameInterpolation = true
playerView.segments = (0, 60) // play frames 0–60
// Read state
let isPlaying = playerView.isAnimationPlaying
let frame = playerView.currentFrame
let progress = playerView.currentProgress
let total = playerView.totalFramesPlayback methods
playerView.play()
playerView.pause()
playerView.stop()
// Play between progress values
playerView.play(fromProgress: 0.0, toProgress: 0.5, loopMode: .playOnce)
// Play between frames
playerView.play(fromFrame: 0, toFrame: 60, loopMode: .loop)
// Play a marker segment
playerView.play(marker: "intro", loopMode: .playOnce)
// Play between two markers
playerView.play(fromMarker: "intro", toMarker: "outro", loopMode: .loop)
// Seek
playerView.setFrame(30)
playerView.setProgress(0.5)Animation loaded callback
playerView.animationLoaded = {
print("Animation is ready!")
}Using DotLottieAnimation (Lower-Level)
DotLottieAnimation is a view model that provides direct control. Use .view() for both SwiftUI and UIKit.
SwiftUI
import SwiftUI
import DotLottie
struct ContentView: View {
@StateObject var animation = DotLottieAnimation(
fileName: "animation",
config: AnimationConfig(autoplay: true, loop: true)
)
var body: some View {
VStack {
animation.view()
.frame(width: 300, height: 300)
HStack {
Button("Play") { animation.play() }
Button("Pause") { animation.pause() }
Button("Stop") { animation.stop() }
}
}
}
}UIKit
import UIKit
import DotLottie
class ViewController: UIViewController {
var dotLottieAnimation: DotLottieAnimation?
override func viewDidLoad() {
super.viewDidLoad()
let config = AnimationConfig(autoplay: true, loop: true)
dotLottieAnimation = DotLottieAnimation(fileName: "animation", config: config)
if let animation = dotLottieAnimation {
let animationView = animation.view()
animationView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
view.addSubview(animationView)
}
}
}Loading from URL
dotLottieAnimation = DotLottieAnimation(
webURL: "https://example.com/animation.lottie",
config: AnimationConfig(autoplay: true, loop: true)
)Playback Control
Control animation playback using methods on the DotLottieAnimation instance:
// Start playing
dotLottieAnimation?.play()
// Pause
dotLottieAnimation?.pause()
// Stop and reset to initial frame
dotLottieAnimation?.stop()
// Set looping
dotLottieAnimation?.setLoop(loop: true)
// Set speed (1.0 = normal)
dotLottieAnimation?.setSpeed(speed: 2.0)
// Set playback mode
dotLottieAnimation?.setMode(mode: .reverse)
// Seek to a specific frame
dotLottieAnimation?.setFrame(frame: 50.0)
// Seek to a progress value (0.0–1.0)
dotLottieAnimation?.setProgress(progress: 0.5)
// Play from a specific frame
dotLottieAnimation?.play(fromFrame: 10.0)
// Play from a specific progress
dotLottieAnimation?.play(fromProgress: 0.25)Event Handling
Subscribe an Observer to receive animation playback events.
class MyObserver: Observer {
func onComplete() { print("Animation Completed") }
func onFrame(frameNo: Float) { }
func onLoad() { print("Animation Loaded") }
func onLoadError() { print("Load Error") }
func onLoop(loopCount: UInt32) { print("Looped \(loopCount) times") }
func onPause() { print("Paused") }
func onPlay() { print("Playing") }
func onRender(frameNo: Float) { }
func onStop() { print("Stopped") }
}
let animation = DotLottieAnimation(fileName: "animation", config: config)
let myObserver = MyObserver()
// Subscribe
animation.subscribe(observer: myObserver)
// Unsubscribe when done
animation.unsubscribe(observer: myObserver)Layout Configuration
Define how the animation fits and aligns within the view bounds using the Layout object in AnimationConfig.
let layoutConfig = Layout(
fit: .cover, // .contain, .cover, .fill, .fitWidth, .fitHeight, .none
align: [0.0, 0.0] // [x, y]: [0,0]=TopLeft, [0.5,0.5]=Center, [1,1]=BottomRight
)
let config = AnimationConfig(layout: layoutConfig)
let anim = DotLottieAnimation(fileName: "animation", config: config)| Property | Type | Default | Description |
fit | Fit | .contain | How the animation scales: .contain, .cover, .fill, .fitWidth, .fitHeight, .none. |
align | [Float] | [0.5, 0.5] | Alignment [x, y]. [0, 0] = top-left, [0.5, 0.5] = center, [1, 1] = bottom-right. |
Using Markers
Control playback based on named markers defined within the Lottie animation.
List Markers:
let markers = dotLottieAnimation?.markers()
print("Available markers: \(markers ?? [])")Play a Segment Defined by a Marker on Load:
let config = AnimationConfig(marker: "intro")
let anim = DotLottieAnimation(fileName: "animation", config: config)Set Marker Programmatically:
dotLottieAnimation?.setMarker(marker: "outro")
dotLottieAnimation?.play()Reset/Clear Marker:
dotLottieAnimation?.setMarker(marker: "")Handling Multiple Animations
A single .lottie file can contain multiple animations.
List Animations:
if let manifest = dotLottieAnimation?.manifest() {
print("Available animation IDs: \(manifest.animations.map { $0.id })")
}Load and Play a Specific Animation by ID:
dotLottieAnimation?.loadAnimation(animationId: "explosion")
dotLottieAnimation?.play()Load via Config:
let config = AnimationConfig(animationId: "explosion")
let anim = DotLottieAnimation(fileName: "multi_animation", config: config)Theming
Apply themes defined within the .lottie file or load theme data dynamically. See Theming Blog Post for theme creation details.
Load Theme by ID on Init:
let config = AnimationConfig(themeId: "darkMode")
let anim = DotLottieAnimation(fileName: "themedAnimation", config: config)Set Theme Programmatically:
let success = dotLottieAnimation?.setTheme("lightMode")Load Theme Data Dynamically:
let success = dotLottieAnimation?.setThemeData(themeJSONData)Reset Theme:
dotLottieAnimation?.resetTheme()Get Active Theme ID:
let currentTheme = dotLottieAnimation?.activeThemeId()Slots
Slots allow dynamic replacement of animation elements. You can use a raw JSON string or typed slot methods.
Raw JSON Slots
let success = dotLottieAnimation?.setSlots(slotJSONData)Typed Slot Methods
// Set a color slot (RGB values from 0.0 to 1.0)
dotLottieAnimation?.setColorSlot(slotId: "primaryColor", r: 1.0, g: 0.0, b: 0.5)
// Set a text slot
dotLottieAnimation?.setTextSlot(slotId: "title", text: "Hello World")
// Set a scalar slot
dotLottieAnimation?.setScalarSlot(slotId: "opacity", value: 0.8)
// Set a vector slot
dotLottieAnimation?.setVectorSlot(slotId: "scale", x: 2.0, y: 2.0)
// Set a position slot
dotLottieAnimation?.setPositionSlot(slotId: "offset", x: 100.0, y: 50.0)
// Set an image slot from a file path
dotLottieAnimation?.setImageSlotPath(slotId: "avatar", path: "/path/to/image.png")
// Set an image slot from a data URL
dotLottieAnimation?.setImageSlotDataUrl(slotId: "avatar", dataUrl: "data:image/png;base64,...")
// Clear a specific slot
dotLottieAnimation?.clearSlot(slotId: "primaryColor")
// Clear all slots
dotLottieAnimation?.clearSlots()Using State Machines (Interactivity)
Note: Interactivity using state machines is currently in its early stages of development and considered experimental. The API might change in future releases.
Interact with state machines defined within your .lottie file to create interactive animations.
1. Load and Start a State Machine:
if dotLottieAnimation?.stateMachineLoad(id: "button_interactions") ?? false {
print("State machine loaded successfully.")
if dotLottieAnimation?.stateMachineStart() ?? false {
print("State machine started.")
}
}2. Post Events to the State Machine:
// Post a click event
dotLottieAnimation?.stateMachinePostEvent(Event.click(x: 150, y: 150))
// Post a pointer event
dotLottieAnimation?.stateMachinePostEvent(Event.pointerDown(x: 10, y: 20))
// Post a completion event
dotLottieAnimation?.stateMachinePostEvent(Event.onComplete)
// Fire a named event
dotLottieAnimation?.stateMachineFire(event: "click")3. Stop the State Machine:
dotLottieAnimation?.stateMachineStop()For more details, see Understanding State Machines.