Core view components for displaying Lottie animations across different UI frameworks including UIKit, Core Animation layers, and SwiftUI integration.
Primary UIKit view for rendering Lottie animations with full control over playback, configuration, and dynamic properties.
/**
* Primary UIKit view for rendering Lottie animations
* Inherits from UIView on iOS/tvOS, NSView on macOS
*/
open class LottieAnimationView: UIView {
// MARK: - Initializers
/**
* Initialize with animation and optional providers
* @param animation - The LottieAnimation to display
* @param imageProvider - Provider for external images
* @param textProvider - Provider for dynamic text replacement
* @param fontProvider - Provider for custom fonts
* @param configuration - Animation configuration
* @param logger - Custom logger instance
*/
public init(
animation: LottieAnimation?,
imageProvider: AnimationImageProvider = BundleImageProvider(bundle: Bundle.main),
textProvider: AnimationKeypathTextProvider = DefaultTextProvider(),
fontProvider: AnimationFontProvider = DefaultFontProvider(),
configuration: LottieConfiguration = .shared,
logger: LottieLogger = .shared
)
/**
* Initialize with DotLottie file and animation ID
* @param dotLottie - DotLottie file containing multiple animations
* @param animationId - Specific animation ID to display
*/
public init(
dotLottie: DotLottieFile?,
animationId: String = "",
textProvider: AnimationKeypathTextProvider = DefaultTextProvider(),
fontProvider: AnimationFontProvider = DefaultFontProvider(),
configuration: LottieConfiguration = .shared,
logger: LottieLogger = .shared
)
/**
* Initialize with configuration only (animation set later)
*/
public init(
configuration: LottieConfiguration = .shared,
logger: LottieLogger = .shared
)
// MARK: - Core Properties
/** The backing animation model */
public var animation: LottieAnimation? { get set }
/** Called when animation loads successfully */
public var animationLoaded: ((LottieAnimationView, LottieAnimation) -> Void)?
/** Provider for external images referenced in animation */
public var imageProvider: AnimationImageProvider { get set }
/** Provider for dynamic text replacement */
public var textProvider: AnimationKeypathTextProvider { get set }
/** Provider for custom fonts */
public var fontProvider: AnimationFontProvider { get set }
/** Global configuration for rendering and behavior */
public var configuration: LottieConfiguration { get set }
// MARK: - Playback Properties
/** Animation loop behavior */
public var loopMode: LottieLoopMode { get set }
/** Playback speed multiplier (1.0 = normal speed) */
public var animationSpeed: CGFloat { get set }
/** Current progress from 0.0 to 1.0 */
public var currentProgress: AnimationProgressTime { get set }
/** Current time in seconds */
public var currentTime: TimeInterval { get set }
/** Current frame number */
public var currentFrame: AnimationFrameTime { get set }
/** Real-time frame while animation is playing */
public var realtimeAnimationFrame: AnimationFrameTime { get }
/** Real-time progress while animation is playing */
public var realtimeAnimationProgress: AnimationProgressTime { get }
/** Whether animation is currently playing */
public var isAnimationPlaying: Bool { get }
/** Whether animation will play when added to window hierarchy */
public var isAnimationQueued: Bool { get }
/** Background behavior when app moves to background */
public var backgroundBehavior: LottieBackgroundBehavior { get set }
/** Current rendering engine in use */
public var currentRenderingEngine: RenderingEngine? { get }
/** Current playback mode configuration */
public var currentPlaybackMode: LottiePlaybackMode? { get }
// MARK: - Playback Methods
/**
* Play animation from current state to end
* @param completion - Called when animation completes or is interrupted
*/
public func play(completion: LottieCompletionBlock? = nil)
/**
* Play animation between specific progress values
* @param fromProgress - Starting progress (0.0 to 1.0)
* @param toProgress - Ending progress (0.0 to 1.0)
* @param loopMode - Loop behavior for this playback
* @param completion - Called when animation completes or is interrupted
*/
public func play(
fromProgress: AnimationProgressTime,
toProgress: AnimationProgressTime,
loopMode: LottieLoopMode? = nil,
completion: LottieCompletionBlock? = nil
)
/**
* Play animation between specific frames
* @param fromFrame - Starting frame number
* @param toFrame - Ending frame number
* @param loopMode - Loop behavior for this playback
* @param completion - Called when animation completes or is interrupted
*/
public func play(
fromFrame: AnimationFrameTime,
toFrame: AnimationFrameTime,
loopMode: LottieLoopMode? = nil,
completion: LottieCompletionBlock? = nil
)
/**
* Play animation between markers
* @param fromMarker - Starting marker name
* @param toMarker - Ending marker name
* @param playEndMarkerFrame - Whether to include end marker frame
* @param loopMode - Loop behavior for this playback
* @param completion - Called when animation completes or is interrupted
*/
public func play(
fromMarker: String,
toMarker: String,
playEndMarkerFrame: Bool = true,
loopMode: LottieLoopMode? = nil,
completion: LottieCompletionBlock? = nil
)
/**
* Play a single marker's animation
* @param marker - Marker name to play
* @param loopMode - Loop behavior for this playback
* @param completion - Called when animation completes or is interrupted
*/
public func play(
marker: String,
loopMode: LottieLoopMode? = nil,
completion: LottieCompletionBlock? = nil
)
/**
* Play multiple markers sequentially
* @param markers - Array of marker names to play in order
* @param completion - Called when all markers complete or are interrupted
*/
public func play(
markers: [String],
completion: LottieCompletionBlock? = nil
)
/**
* Apply a playback mode configuration
* @param playbackMode - Complete playback mode specification
* @param completion - Called when animation completes or is interrupted
*/
public func setPlaybackMode(
_ playbackMode: LottiePlaybackMode,
completion: LottieCompletionBlock? = nil
)
/** Stop animation and reset to beginning */
public func stop()
/** Pause animation at current frame */
public func pause()
/**
* Pause animation at specific state
* @param at - Paused state specification
*/
public func pause(at pausedState: PausedState)
}Usage Examples:
import Lottie
import UIKit
class AnimationViewController: UIViewController {
let animationView = LottieAnimationView()
override func viewDidLoad() {
super.viewDidLoad()
// Load animation from bundle
animationView.animation = LottieAnimation.named("loading")
animationView.frame = view.bounds
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
view.addSubview(animationView)
// Set up animation loaded callback
animationView.animationLoaded = { view, animation in
print("Animation loaded: \(animation.duration) seconds")
view.play()
}
// Play specific segment
animationView.play(
fromProgress: 0.2,
toProgress: 0.8,
loopMode: .autoReverse
) { finished in
print("Segment playback finished: \(finished)")
}
// Play between markers
animationView.play(
fromMarker: "intro",
toMarker: "outro",
loopMode: .playOnce
)
}
}Core Animation layer for rendering Lottie animations, providing lower-level control and integration with existing CALayer hierarchies.
/**
* Core Animation layer for rendering Lottie animations
* Inherits from CALayer
*/
public class LottieAnimationLayer: CALayer {
// MARK: - Initializers
/**
* Initialize with animation and optional providers
* @param animation - The LottieAnimation to display
* @param imageProvider - Provider for external images
* @param textProvider - Provider for dynamic text replacement
* @param fontProvider - Provider for custom fonts
* @param configuration - Animation configuration
* @param logger - Custom logger instance
*/
public init(
animation: LottieAnimation?,
imageProvider: AnimationImageProvider = BundleImageProvider(bundle: Bundle.main),
textProvider: AnimationKeypathTextProvider = DefaultTextProvider(),
fontProvider: AnimationFontProvider = DefaultFontProvider(),
configuration: LottieConfiguration = .shared,
logger: LottieLogger = .shared
)
/**
* Initialize with DotLottie file and animation ID
*/
public init(
dotLottie: DotLottieFile?,
animationId: String = "",
textProvider: AnimationKeypathTextProvider = DefaultTextProvider(),
fontProvider: AnimationFontProvider = DefaultFontProvider(),
configuration: LottieConfiguration = .shared,
logger: LottieLogger = .shared
)
// MARK: - Layer-Specific Properties
/** Called when animation layer loads with rendering engine info */
public var animationLayerDidLoad: ((LottieAnimationLayer, RenderingEngineOption) -> Void)?
/** Screen scale factor for rendering quality */
public var screenScale: CGFloat { get set }
// MARK: - All LottieAnimationView properties and methods are available
// (Inherits same API surface for playback, dynamic properties, etc.)
}Usage Examples:
import Lottie
import UIKit
class LayerAnimationViewController: UIViewController {
let animationLayer = LottieAnimationLayer()
override func viewDidLoad() {
super.viewDidLoad()
// Configure animation layer
animationLayer.animation = LottieAnimation.named("background")
animationLayer.frame = view.layer.bounds
animationLayer.loopMode = .loop
// Add to layer hierarchy
view.layer.addSublayer(animationLayer)
// Set up layer loaded callback
animationLayer.animationLayerDidLoad = { layer, renderingEngine in
print("Layer loaded with engine: \(renderingEngine)")
layer.play()
}
// Configure screen scale for high DPI displays
animationLayer.screenScale = UIScreen.main.scale
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
animationLayer.frame = view.layer.bounds
}
}SwiftUI view wrapper providing declarative animation integration with modifier-based configuration.
/**
* SwiftUI wrapper for Lottie animations
* Conforms to View protocol
*/
public struct LottieView: View {
// MARK: - Initializers
/**
* Initialize with LottieAnimation
* @param animation - The animation to display
*/
public init(animation: LottieAnimation?)
/**
* Initialize with DotLottieFile
* @param dotLottieFile - DotLottie file containing animations
*/
public init(dotLottieFile: DotLottieFile?)
/**
* Initialize with async loading and placeholder
* @param url - URL to load animation from
* @param placeholder - View to show while loading
*/
public init<PlaceholderView: View>(
_ url: URL,
@ViewBuilder placeholder: () -> PlaceholderView
)
/**
* Initialize with async loading without placeholder
* @param url - URL to load animation from
*/
public init(_ url: URL)
// MARK: - Configuration Methods
/**
* Configure a specific property
* @param property - Keypath to property
* @param value - Value to set
*/
public func configure<T>(_ property: ReferenceWritableKeyPath<LottieAnimationView, T>, to value: T) -> LottieView
/**
* Configure with closure
* @param configuration - Configuration closure receiving view
*/
public func configure(_ configuration: @escaping (LottieAnimationView) -> Void) -> LottieView
/**
* Make view resizable (ignores intrinsic size)
*/
public func resizable() -> LottieView
/**
* Use intrinsic animation size
*/
public func intrinsicSize() -> LottieView
// MARK: - Playback Configuration
/**
* Set playback mode
* @param playbackMode - Complete playback mode specification
*/
public func playing(_ playbackMode: LottiePlaybackMode) -> LottieView
/**
* Set loop mode for playing
* @param loopMode - Loop behavior
*/
public func playing(loopMode: LottieLoopMode) -> LottieView
/**
* Play animation once from beginning to end
*/
public func playing() -> LottieView
/**
* Loop animation continuously
*/
public func looping() -> LottieView
/**
* Pause at specific state
* @param pausedState - Where to pause animation
*/
public func paused(at pausedState: PausedState) -> LottieView
/**
* Set complete playback mode
* @param playbackMode - Playback mode configuration
*/
public func playbackMode(_ playbackMode: LottiePlaybackMode) -> LottieView
/**
* Set animation speed multiplier
* @param speed - Speed multiplier (1.0 = normal)
*/
public func animationSpeed(_ speed: CGFloat) -> LottieView
// MARK: - Provider Configuration
/**
* Set animation configuration
* @param configuration - Global configuration
*/
public func configuration(_ configuration: LottieConfiguration) -> LottieView
/**
* Set logger instance
* @param logger - Custom logger
*/
public func logger(_ logger: LottieLogger) -> LottieView
/**
* Set image provider
* @param imageProvider - Provider for external images
*/
public func imageProvider(_ imageProvider: AnimationImageProvider) -> LottieView
/**
* Set text provider
* @param textProvider - Provider for dynamic text
*/
public func textProvider(_ textProvider: AnimationKeypathTextProvider) -> LottieView
/**
* Set font provider
* @param fontProvider - Provider for custom fonts
*/
public func fontProvider(_ fontProvider: AnimationFontProvider) -> LottieView
/**
* Set value provider for keypath
* @param valueProvider - Provider for dynamic values
* @param keypath - Target keypath
*/
public func valueProvider<ValueProvider: AnyValueProvider>(
_ valueProvider: ValueProvider,
for keypath: AnimationKeypath
) -> LottieView
// MARK: - State Configuration
/**
* Set current progress
* @param progress - Progress value (0.0 to 1.0)
*/
public func currentProgress(_ progress: AnimationProgressTime) -> LottieView
/**
* Set current frame
* @param frame - Frame number
*/
public func currentFrame(_ frame: AnimationFrameTime) -> LottieView
/**
* Set current time
* @param time - Time in seconds
*/
public func currentTime(_ time: TimeInterval) -> LottieView
/**
* Set background behavior
* @param behavior - Behavior when app backgrounds
*/
public func backgroundBehavior(_ behavior: LottieBackgroundBehavior) -> LottieView
/**
* Set accessibility label
* @param accessibilityLabel - Label for accessibility
*/
public func accessibilityLabel(_ accessibilityLabel: String) -> LottieView
}Usage Examples:
import SwiftUI
import Lottie
struct ContentView: View {
@State private var isPlaying = false
@State private var progress: CGFloat = 0.0
var body: some View {
VStack {
// Basic looping animation
LottieView(animation: .named("celebration"))
.looping()
.resizable()
.frame(width: 200, height: 200)
// Controlled animation with custom configuration
LottieView(animation: .named("loading"))
.playing(isPlaying ? .playing(.fromProgress(0, toProgress: 1, loopMode: .loop)) : .paused(at: .progress(progress)))
.animationSpeed(2.0)
.configuration(.init(renderingEngine: .coreAnimation))
.resizable()
.frame(width: 150, height: 150)
// Interactive controls
HStack {
Button("Play") { isPlaying = true }
Button("Pause") { isPlaying = false }
Slider(value: $progress, in: 0...1)
}
.padding()
// Async loading with placeholder
LottieView(URL(string: "https://example.com/animation.json")!) {
ProgressView("Loading animation...")
.frame(width: 200, height: 200)
}
.playing()
}
}
}
// Custom modifier for common configuration
extension LottieView {
func standardAnimation() -> some View {
self
.resizable()
.animationSpeed(1.0)
.backgroundBehavior(.pause)
.configuration(.shared)
}
}All animation view types support dynamic property modification through keypaths and value providers.
/**
* Dynamic property methods available on all animation views
*/
extension LottieAnimationView {
/**
* Set value provider for keypath
* @param valueProvider - Provider for dynamic values
* @param keypath - Target animation keypath
*/
public func setValueProvider<ValueProvider: AnyValueProvider>(
_ valueProvider: ValueProvider,
keypath: AnimationKeypath
)
/**
* Remove value provider for keypath
* @param keypath - Target keypath to remove provider from
*/
public func removeValueProvider(for keypath: AnimationKeypath)
/**
* Get current value for keypath at specific frame
* @param keypath - Target keypath
* @param atFrame - Frame to query value at
* @returns Current value including any applied providers
*/
public func getValue(for keypath: AnimationKeypath, atFrame: AnimationFrameTime) -> Any?
/**
* Get original animation value for keypath at specific frame
* @param keypath - Target keypath
* @param atFrame - Frame to query value at
* @returns Original value ignoring any applied providers
*/
public func getOriginalValue(for keypath: AnimationKeypath, atFrame: AnimationFrameTime) -> Any?
}Methods for inspecting animation structure and integrating with custom views.
/**
* Hierarchy inspection and layout methods
*/
extension LottieAnimationView {
/** Log all available keypaths to console */
public func logHierarchyKeypaths()
/**
* Get all available keypaths in animation
* @returns Array of keypath strings
*/
public func allHierarchyKeypaths() -> [String]
/**
* Add subview to animation layer at keypath
* @param subview - UIView to add
* @param keypath - Target layer keypath
*/
public func addSubview(_ subview: UIView, forLayerAt keypath: AnimationKeypath)
/**
* Convert rectangle to layer coordinate space
* @param rect - Rectangle to convert
* @param keypath - Target layer keypath
* @returns Converted rectangle, nil if keypath not found
*/
public func convert(_ rect: CGRect, toLayerAt keypath: AnimationKeypath) -> CGRect?
/**
* Convert point to layer coordinate space
* @param point - Point to convert
* @param keypath - Target layer keypath
* @returns Converted point, nil if keypath not found
*/
public func convert(_ point: CGPoint, toLayerAt keypath: AnimationKeypath) -> CGPoint?
/**
* Enable or disable nodes at keypath
* @param isEnabled - Whether nodes should be enabled
* @param keypath - Target keypath
*/
public func setNodeIsEnabled(isEnabled: Bool, keypath: AnimationKeypath)
}