# dotLottie iOS Player Examples
Practical examples for the dotLottie iOS player using DotLottiePlayerView (SwiftUI), DotLottiePlayerUIView (UIKit), and DotLottieAnimation. Includes playback, events, markers, themes, slots, and WebGPU.

# dotLottie iOS Player Examples

This page provides practical examples for using the dotLottie iOS player.

## Setup

Ensure you have added the DotLottie framework to your project and import it where needed:

```swift
import DotLottie
```

## DotLottiePlayerView (SwiftUI) Examples

### 1. Basic Animation

```swift
import SwiftUI
import DotLottie

struct BasicPlayerView: View {
    var body: some View {
        DotLottiePlayerView(animation: DotLottieAnimation(
            fileName: "animation",
            config: AnimationConfig(autoplay: true, loop: true)
        ))
        .looping()
        .playing()
        .frame(width: 300, height: 300)
    }
}
```

### 2. Async Loading with Placeholder

```swift
import SwiftUI
import DotLottie

struct AsyncPlayerView: View {
    var body: some View {
        DotLottiePlayerView({
            try await DotLottieAnimation(
                webURL: "https://assets.lottiefiles.com/samples/animation.lottie",
                config: AnimationConfig(autoplay: true, loop: true)
            )
        }, placeholder: {
            ProgressView("Loading...")
        })
        .looping()
        .playing()
        .frame(width: 300, height: 300)
    }
}
```

### 3. Custom Speed and Mode

```swift
import SwiftUI
import DotLottie

struct CustomPlayerView: View {
    var body: some View {
        DotLottiePlayerView(animation: DotLottieAnimation(
            fileName: "animation",
            config: AnimationConfig(autoplay: true, loop: true)
        ))
        .looping()
        .playing()
        .animationSpeed(2.0)
        .mode(.bounce)
        .useFrameInterpolation(true)
        .frame(width: 300, height: 300)
    }
}
```

### 4. Animation Loaded Callback

```swift
import SwiftUI
import DotLottie

struct CallbackPlayerView: View {
    var body: some View {
        DotLottiePlayerView(animation: DotLottieAnimation(
            fileName: "animation",
            config: AnimationConfig(autoplay: true, loop: true)
        ))
        .looping()
        .playing()
        .animationDidLoad { animation in
            print("Animation is ready: \(animation?.totalFrames() ?? 0) frames")
        }
        .frame(width: 300, height: 300)
    }
}
```

### 5. Segment Playback

```swift
import SwiftUI
import DotLottie

struct SegmentPlayerView: View {
    var body: some View {
        DotLottiePlayerView(animation: DotLottieAnimation(
            fileName: "animation",
            config: AnimationConfig(autoplay: true, loop: true)
        ))
        .looping()
        .playing()
        .segments((0, 60)) // Play only frames 0–60
        .frame(width: 300, height: 300)
    }
}
```

### 6. Dynamic Layout

```swift
import SwiftUI
import DotLottie

struct LayoutPlayerView: View {
    private let animation = DotLottieAnimation(
        fileName: "animation",
        config: AnimationConfig(
            autoplay: true,
            loop: true,
            layout: Layout(fit: .contain, alignX: 0.5, alignY: 0.5)
        )
    )

    var body: some View {
        VStack {
            DotLottiePlayerView(animation: animation)
                .looping()
                .frame(height: 200)

            Button("Switch to Cover") {
                animation.setLayout(layout: Layout(fit: .cover, alignX: 0.5, alignY: 0.5))
            }
        }
    }
}
```

---

## DotLottiePlayerUIView (UIKit) Examples

### 1. Basic Animation

```swift
import UIKit
import DotLottie

class BasicUIKitController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        let playerView = DotLottiePlayerUIView(
            name: "animation",
            config: AnimationConfig(autoplay: true, loop: true)
        )
        playerView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
        view.addSubview(playerView)
    }
}
```

### 2. With Playback Controls

```swift
import UIKit
import DotLottie

class ControlledUIKitController: UIViewController {
    var playerView: DotLottiePlayerUIView!

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

        playerView = DotLottiePlayerUIView(
            name: "animation",
            config: AnimationConfig(autoplay: false, loop: false)
        )
        playerView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
        view.addSubview(playerView)

        setupControls()
    }

    func setupControls() {
        let playButton = UIButton(type: .system)
        playButton.setTitle("Play", for: .normal)
        playButton.addTarget(self, action: #selector(playTapped), for: .touchUpInside)
        playButton.frame = CGRect(x: 50, y: 420, width: 80, height: 40)
        view.addSubview(playButton)

        let pauseButton = UIButton(type: .system)
        pauseButton.setTitle("Pause", for: .normal)
        pauseButton.addTarget(self, action: #selector(pauseTapped), for: .touchUpInside)
        pauseButton.frame = CGRect(x: 150, y: 420, width: 80, height: 40)
        view.addSubview(pauseButton)

        let stopButton = UIButton(type: .system)
        stopButton.setTitle("Stop", for: .normal)
        stopButton.addTarget(self, action: #selector(stopTapped), for: .touchUpInside)
        stopButton.frame = CGRect(x: 250, y: 420, width: 80, height: 40)
        view.addSubview(stopButton)
    }

    @objc func playTapped() { playerView.play() }
    @objc func pauseTapped() { playerView.pause() }
    @objc func stopTapped() { playerView.stop() }
}
```

### 3. Loading from URL

```swift
import UIKit
import DotLottie

class URLUIKitController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        let playerView = DotLottiePlayerUIView(
            url: URL(string: "https://assets.lottiefiles.com/samples/animation.lottie")!,
            config: AnimationConfig(autoplay: true, loop: true)
        )
        playerView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
        view.addSubview(playerView)
    }
}
```

### 4. Marker Playback

```swift
import UIKit
import DotLottie

class MarkerUIKitController: UIViewController {
    var playerView: DotLottiePlayerUIView!

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

        playerView = DotLottiePlayerUIView(
            name: "animation_with_markers",
            config: AnimationConfig(autoplay: true, loop: false, marker: "intro")
        )
        playerView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
        view.addSubview(playerView)

        // List available markers
        let markers = playerView.markers()
        print("Available markers: \(markers)")

        // Switch to a different marker
        playerView.play(marker: "outro", loopMode: .playOnce)
    }
}
```

### 5. Animation Loaded Callback

```swift
import UIKit
import DotLottie

class CallbackUIKitController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        let playerView = DotLottiePlayerUIView(
            name: "animation",
            config: AnimationConfig(autoplay: true, loop: true)
        )
        playerView.frame = CGRect(x: 50, y: 100, width: 300, height: 300)
        view.addSubview(playerView)

        playerView.animationLoaded = { view, animation in
            print("Animation loaded — total frames: \(playerView.totalFrames)")
        }
    }
}
```

---

## DotLottieAnimation Examples

### 1. Basic Animation (SwiftUI)

```swift
import SwiftUI
import DotLottie

struct BasicSwiftUIView: 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)
        }
    }
}
```

### 2. Controlled Animation (SwiftUI)

```swift
import SwiftUI
import DotLottie

struct ControlledSwiftUIView: View {
    @StateObject var animation = DotLottieAnimation(
        fileName: "animation",
        config: AnimationConfig(autoplay: false, loop: false)
    )

    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() }
            }
            .padding()
        }
    }
}
```

### 3. Event Handling with Observer

```swift
import UIKit
import DotLottie

class MyAnimationObserver: Observer {
    func onLoad() { print("Loaded") }
    func onPlay() { print("Play") }
    func onPause() { print("Pause") }
    func onStop() { print("Stop") }
    func onComplete() { print("Complete") }
    func onLoop(loopCount: UInt32) { print("Loop \(loopCount)") }
    func onFrame(frameNo: Float) { }
    func onRender(frameNo: Float) { }
    func onLoadError() { print("Load Error") }
}

class EventUIKitController: UIViewController {
    var dotLottieAnimation: DotLottieAnimation?
    let observer = MyAnimationObserver()

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

        let config = AnimationConfig(autoplay: true, loop: false)
        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)

            // Subscribe the observer
            animation.subscribe(observer: observer)
        }
    }

    deinit {
        dotLottieAnimation?.unsubscribe(observer: observer)
    }
}
```

### 4. Theming

```swift
import SwiftUI
import DotLottie

struct ThemedView: View {
    @StateObject var animation = DotLottieAnimation(
        fileName: "themed_animation",
        config: AnimationConfig(autoplay: true, loop: true, themeId: "dark")
    )

    var body: some View {
        VStack {
            animation.view()
                .frame(width: 300, height: 300)

            HStack {
                Button("Light") { animation.setTheme("light") }
                Button("Dark") { animation.setTheme("dark") }
                Button("Reset") { animation.resetTheme() }
            }
        }
    }
}
```

### 5. Typed Slots

```swift
import SwiftUI
import DotLottie

struct SlotView: View {
    @StateObject var animation = DotLottieAnimation(
        fileName: "slotted_animation",
        config: AnimationConfig(autoplay: true, loop: true)
    )

    var body: some View {
        VStack {
            animation.view()
                .frame(width: 300, height: 300)

            Button("Apply Red") {
                animation.setColorSlot(slotId: "primaryColor", r: 1.0, g: 0.0, b: 0.0)
            }
            Button("Change Text") {
                animation.setTextSlot(slotId: "title", text: "Hello!")
            }
            Button("Clear All Slots") {
                animation.clearSlots()
            }
        }
    }
}
```

### 6. State Machine

```swift
import SwiftUI
import DotLottie

struct StateMachineView: View {
    @StateObject var animation = DotLottieAnimation(
        fileName: "interactive_animation",
        config: AnimationConfig()
    )

    class MyObserver: StateMachineObserver {
        func onTransition(previousState: String, newState: String) {
            print("Transition: \(previousState) -> \(newState)")
        }
        func onStateEntered(enteringState: String) {
            print("Entered: \(enteringState)")
        }
        func onStateExit(leavingState: String) {
            print("Exited: \(leavingState)")
        }
    }

    let smObserver = MyObserver()

    var body: some View {
        VStack {
            animation.view()
                .frame(height: 300)
                .onAppear {
                    if animation.stateMachineLoad(id: "myFSM") {
                        animation.stateMachineSubscribe(smObserver)
                        animation.stateMachineStart()
                    }
                }
                .onDisappear {
                    animation.stateMachineStop()
                    animation.stateMachineUnsubscribe(smObserver)
                }

            Button("Click") {
                animation.stateMachinePostEvent(Event.click(x: 150, y: 150))
            }
        }
    }
}
```

---

## WebGPU Renderer Examples (Experimental)

The WebGPU renderer is available on iOS (excluding Mac Catalyst) and macOS only.

### SwiftUI — Basic WebGPU Animation

```swift
import SwiftUI
import DotLottie

struct WebGPUPlayerView: View {
    var body: some View {
        DotLottieWebGPUPlayerView(
            fileName: "animation",
            config: Config(autoplay: true, loopAnimation: true)
        )
        .frame(height: 300)
    }
}
```

### SwiftUI — WebGPU with Runtime Control

```swift
import SwiftUI
import DotLottie

struct WebGPUControlView: View {
    @State private var gpuView: DotLottieWebGPUView?

    var body: some View {
        VStack {
            DotLottieWebGPUPlayerView(
                fileName: "animation",
                config: Config(autoplay: true, loopAnimation: true)
            ) { view in
                // Called asynchronously after the view is created
                gpuView = view
            }
            .frame(height: 300)

            HStack {
                Button("Play")  { gpuView?.play() }
                Button("Pause") { gpuView?.pause() }
                Button("Stop")  { gpuView?.stop() }
            }
        }
    }
}
```

### SwiftUI — WebGPU State Machine

```swift
import SwiftUI
import DotLottie

struct WebGPUStateMachineView: View {
    @State private var gpuView: DotLottieWebGPUView?

    var body: some View {
        VStack {
            // State machine auto-starts when the animation loads
            DotLottieWebGPUPlayerView(
                fileName: "interactive_animation",
                config: Config(
                    autoplay: true,
                    loopAnimation: true,
                    stateMachineId: "myFSM"
                )
            ) { view in
                gpuView = view
            }
            .frame(height: 300)

            Button("Fire Event") {
                gpuView?.player.stateMachineFireEvent(event: "buttonClicked")
            }
        }
    }
}
```

### UIKit — DotLottieWebGPUView

```swift
import UIKit
import DotLottie

class WebGPUViewController: UIViewController {
    private var gpuView: DotLottieWebGPUView!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .black

        gpuView = DotLottieWebGPUView(
            config: Config(autoplay: true, loopAnimation: true)
        )
        gpuView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(gpuView)

        NSLayoutConstraint.activate([
            gpuView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            gpuView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            gpuView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            gpuView.heightAnchor.constraint(equalToConstant: 300)
        ])

        gpuView.loadAnimation(fileName: "animation")
    }
}
```
