कंटेंट पर जाएँ
charmotion

SwiftUI में Lottie: LottieView, प्लेबैक और लूपिंग

Charmotion टीम द्वारा · अपडेट:

iOS और Swift गाइड का कवर इलस्ट्रेशन: SwiftUI में Lottie: LottieView, प्लेबैक और लूपिंग, Charmotion के डेमो कैरेक्टर के साथ

SwiftUI में Lottie इस्तेमाल करने के लिए lottie-spm package जोड़ें और LottieView(animation: .named("idle")).looping() लिखें। वन-शॉट के लिए .playing(loopMode: .playOnce), ranges के लिए .playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop))), और खत्म होने पर प्रतिक्रिया के लिए .animationDidFinish इस्तेमाल करें। Lottie iOS, macOS, tvOS और visionOS सपोर्ट करता है, watchOS नहीं।

मुख्य बातें

  • https://github.com/airbnb/lottie-spm.git से install करें: Airbnb के अनुसार इसे clone करने का साइज़ 500 KB से कम है, जबकि main repo 300 MB से ज़्यादा है।
  • LottieView एक SwiftUI view है जिसमें chain किए जा सकने वाले modifiers हैं: .looping(), .playing(loopMode:), .playbackMode(_:), .resizable()।
  • Named markers की मदद से एक ही फ़ाइल में कई segments रखे जा सकते हैं, जिन्हें आप .marker(_:loopMode:) से चुनते हैं।
  • अगर फ़ाइल में "reduced motion" marker है, तो Reduce Motion चालू होने पर Lottie उसकी जगह वही चला सकता है।
  • LottieView में data-bound स्टेट मशीन नहीं है; ऐप की स्टेट पर रिएक्ट करने वाले मैस्कॉट के लिए Rive बेहतर विकल्प है।

Swift Package Manager से Lottie कैसे install करें?

Xcode में File → Add Package Dependencies चुनें और https://github.com/airbnb/lottie-spm.git डालें। Airbnb का README SwiftPM के लिए इसी wrapper repository की सलाह देता है, क्योंकि main lottie-ios repository clone करने में 300 MB से ज़्यादा है, जबकि lottie-spm 500 KB से कम है। अपने app target में Lottie library जोड़ें और import Lottie करें।

अपनी animation JSON (या .lottie file) को app target में रखें। LottieAnimation.named("idle") default रूप से main bundle में idle.json ढूँढता है।

lottie-spm manifest iOS, macOS, tvOS और visionOS declare करता है। इसमें watchOS platform नहीं है, जो तब मायने रखता है जब आप Watch app के साथ UI code share करते हैं।

SwiftUI में LottieView कैसे दिखाएँ?

LottieView 4.3.0 से lottie-ios का हिस्सा है। सबसे सरल रूप:

import SwiftUI
import Lottie

struct LoadingMascot: View {
    var body: some View {
        LottieView(animation: .named("loading"))
            .looping()
            .resizable()
            .scaledToFit()
            .frame(width: 180, height: 180)
            .accessibilityLabel("Loading")
    }
}

.resizable() एनिमेशन को resizable Image की तरह उसके frame के हिसाब से scale होने देता है; इसके बिना view एनिमेशन का intrinsic size इस्तेमाल करता है। अन्य initializers में .lottie फ़ाइलों के लिए LottieView(dotLottieFile:) और async-closure variants शामिल हैं, जो एनिमेशन load करते हैं (जैसे किसी URL से) और loading के दौरान placeholder दिखाते हैं।

खर्च पर एक नोट: Lottie हर फ़्रेम में vector shapes render करता है। छोटे लूपिंग मैस्कॉट के लिए यह ठीक है; scrolling list में एक साथ कई एनिमेशन हों, तो list में static image रखें और सिर्फ़ focused item को एनिमेट करें।

LottieView को लूप या एक बार कैसे चलाएँ?

Playback modifiers LottiePlaybackMode से map होते हैं:

// Loop forever
LottieView(animation: .named("idle")).looping()

// Play once and stop on the last frame
LottieView(animation: .named("success")).playing(loopMode: .playOnce)

// Play a progress range on loop
LottieView(animation: .named("idle"))
    .playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))

// Paused on the current frame
LottieView(animation: .named("idle")).paused(at: .currentFrame)

वन-शॉट खत्म होने पर प्रतिक्रिया के लिए .animationDidFinish { completed in … } जोड़ें। ज़रूरत पड़ने पर वन-शॉट दोबारा शुरू करने के लिए playback mode को state से चलाएँ और उसे बदलें:

struct SaveButton: View {
    @State private var playback: LottiePlaybackMode = .paused(at: .progress(0))

    var body: some View {
        VStack {
            LottieView(animation: .named("success"))
                .playbackMode(playback)
                .animationDidFinish { _ in playback = .paused(at: .progress(0)) }
                .frame(width: 120, height: 120)
            Button("Save") {
                playback = .playing(.fromProgress(0, toProgress: 1, loopMode: .playOnce))
            }
        }
    }
}

अन्य loop modes में .autoReverse, .repeat(_:) और .repeatBackwards(_:) शामिल हैं।

क्या अलग-अलग फ़ाइलों के बिना Lottie में मूड बदले जा सकते हैं?

हाँ, मार्कर की मदद से। अगर डिज़ाइनर After Effects या Lottie Creator में नाम वाले मार्कर जोड़ दे (जैसे idle, happy, sad), तो आप एक बार में एक सेगमेंट चला सकते हैं:

enum Mood: String { case idle, happy, sad }

struct MarkerMascot: View {
    let mood: Mood

    var body: some View {
        LottieView(animation: .named("mascot"))
            .playbackMode(.playing(.marker(mood.rawValue, loopMode: .loop)))
            .resizable()
            .scaledToFit()
    }
}

इसके अलावा .fromMarker(_:toMarker:loopMode:) भी है, और .markers([…]) भी, जो कई मार्कर को एक के बाद एक चलाता है। यह "पहले रिएक्ट करें, फिर शांत हो जाएँ" जैसे मामलों में काम आता है।

दिक्कत ट्रांज़िशन की है। मार्कर बदलने पर पुराना सेगमेंट जहाँ भी हो, वहीं से सीधे नए सेगमेंट पर कट हो जाता है। कुछ भी ब्लेंड नहीं होता, जब तक आर्टवर्क इस तरह डिज़ाइन न किया गया हो कि हर सेगमेंट एक ही पोज़ पर शुरू और खत्म हो। यही काम स्टेट मशीन आपके लिए करती है।

LottieView, Reduce Motion को कैसे हैंडल करता है?

Lottie 4.3.0 में reduced-motion सपोर्ट जोड़ा गया। अगर किसी एनिमेशन में reduced motion नाम का मार्कर है (सोर्स reducedMotion, reduced_motion और reduced-motion भी स्वीकार करता है), तो reduced-motion विकल्प चालू होने पर Lottie पूरे एनिमेशन की जगह वही मार्कर चलाता है। डिफ़ॉल्ट रूप से यह सिस्टम सेटिंग को फ़ॉलो करता है।

अगर आपकी फ़ाइल में ऐसा कोई मार्कर नहीं है, तो इसे खुद हैंडल करें:

struct AdaptiveLottie: View {
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    var body: some View {
        LottieView(animation: .named("idle"))
            .playbackMode(reduceMotion ? .paused(at: .progress(0)) : .playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))
            .resizable()
            .scaledToFit()
    }
}

ऐसा पॉज़ फ़्रेम चुनें जो स्थिर पोज़ के रूप में अच्छा दिखे। फ़्रेम 0 अक्सर एक न्यूट्रल पोज़ होता है, लेकिन हमेशा नहीं। और पैटर्न यहाँ देखें: SwiftUI और UIKit में Reduce Motion।

ऐप की स्टेट से LottieView को कैसे चलाएँ?

फ़ैसला अपने model में रखें और view को एनिमेशन चुनने दें। एक छोटा enum फ़ाइल नामों को एक जगह रखता है और वन-शॉट एनिमेशन को साफ़-साफ़ अलग दिखाता है:

enum UploadState: Equatable {
    case idle, uploading, done, failed

    var animationName: String {
        switch self {
        case .idle: return "idle"
        case .uploading: return "loading"
        case .done: return "success"
        case .failed: return "error"
        }
    }

    var loopMode: LottieLoopMode {
        switch self {
        case .idle, .uploading: return .loop
        case .done, .failed: return .playOnce
        }
    }
}

struct UploadMascot: View {
    let state: UploadState

    var body: some View {
        LottieView(animation: .named(state.animationName))
            .playing(loopMode: state.loopMode)
            .resizable()
            .scaledToFit()
            .id(state)                 // new view per state, so each clip starts from frame 0
            .transition(.opacity)
            .animation(.easeInOut(duration: 0.2), value: state)
    }
}

.id(state) स्टेट बदलने पर नया view बनवाता है, जिससे प्लेबैक शुरू से रीस्टार्ट होता है और एक छोटा crossfade कट को छिपा देता है। इसके बिना SwiftUI पुराने view को फिर से इस्तेमाल कर सकता है और पिछले एनिमेशन की प्रोग्रेस बनी रह सकती है। अगर आप मार्कर वाली एक ही फ़ाइल चाहते हैं, तो एनिमेशन के नाम की जगह .playbackMode(.playing(.marker(…, loopMode:))) लिखें, जैसा ऊपर दिखाया गया है।

यहीं कैरेक्टर के लिए Lottie की सीमाएँ भी दिखने लगती हैं: स्टेट मशीन आप खुद लिख रहे होते हैं, एक-एक switch करके।

Lottie किन प्लेटफ़ॉर्म को सपोर्ट करता है?

प्लेटफ़ॉर्मlottie-spmRiveRuntime
iOSYes14.0+
macOSYes13.1+
tvOSYes16.0+
visionOSYes1.0+
watchOSघोषित नहींघोषित नहीं

आप जो वर्ज़न पिन करते हैं, उसका सटीक न्यूनतम वर्ज़न जानने के लिए हर Package.swift में platforms लिस्ट देखें, क्योंकि यह रिलीज़ के साथ बदलता है। कोई भी पैकेज watchOS घोषित नहीं करता, इसलिए Apple Watch के लिए SwiftUI animators या पहले से रेंडर किए गए फ़्रेम चाहिए। देखें: watchOS और visionOS में कैरेक्टर एनिमेशन।

visionOS पर LottieView सामान्य SwiftUI window के अंदर बिल्कुल iPhone की तरह काम करता है। macOS पर वही SwiftUI code कंपाइल होता है, और AppKit ऐप सीधे LottieAnimationView इस्तेमाल कर सकते हैं। iOS पर UIKit स्क्रीन के लिए, LottieView के पीछे की view class LottieAnimationView ही है। इसमें play(), loopMode और animationSpeed प्रॉपर्टी और मेथड के रूप में मिलते हैं।

मैस्कॉट के लिए Lottie की जगह Rive कब चुनें?

Lottie (LottieView)Rive
फ़ॉर्मेटJSON या .lottie, आमतौर पर After Effects या Lottie Creator सेRive editor से बनी बाइनरी .riv
code से स्टेट बदलनाफ़ाइल, मार्कर या प्रोग्रेस रेंज चुनेंनंबर सेट करें या ट्रिगर फ़ायर करें; स्टेट मशीन ट्रांज़िशन करती है
स्टेट के बीच ब्लेंडिंगहाथ से डिज़ाइन करना पड़ता है, वरना सीधा कटस्टेट मशीन ट्रांज़िशन में पहले से मौजूद
दो-तरफ़ा डेटाNoData Binding प्रॉपर्टी और ट्रिगर स्ट्रीम
किसके लिए सहीतय क्लिप: loader, success टिक, इलस्ट्रेशनऐसे कैरेक्टर जो ऐप पर रिएक्ट करते हैं

कई ऐप दोनों इस्तेमाल करते हैं: कुछ सजावटी क्लिप के लिए Lottie, और मैस्कॉट के लिए Rive। mood नंबर और ट्रिगर वाला एक Rive कैरेक्टर उस काम की जगह ले लेता है, जिसके लिए वरना Lottie फ़ाइलों का पूरा फ़ोल्डर और switching logic चाहिए होता। गहराई से तुलना के लिए देखें: Lottie बनाम Rive स्टेट मशीन।

SwiftUI view में लूपिंग Lottie एनिमेशन जोड़ें

  1. पैकेज जोड़ें. Xcode में https://github.com/airbnb/lottie-spm.git जोड़ें और Lottie लाइब्रेरी लिंक करें।
  2. फ़ाइल bundle करें. ऐप target में idle.json (या कोई .lottie फ़ाइल) जोड़ें।
  3. इसे दिखाएँ. frame के साथ LottieView(animation: .named("idle")).looping().resizable().scaledToFit() लिखें।
  4. वन-शॉट एनिमेशन हैंडल करें. .playing(loopMode: .playOnce) और .animationDidFinish इस्तेमाल करें, या स्टेट से .playbackMode चलाएँ।
  5. Reduce Motion सेटिंग का ध्यान रखें. फ़ाइल में "reduced motion" मार्कर जोड़ें, या accessibilityReduceMotion true होने पर किसी स्थिर फ़्रेम पर पॉज़ करें।

अक्सर पूछे जाने वाले सवाल

lottie-ios repository की जगह lottie-spm क्यों इस्तेमाल करें?

दोनों से आपको एक ही Lottie लाइब्रेरी मिलती है। Airbnb, Swift Package Manager के लिए lottie-spm की सलाह देता है, क्योंकि मुख्य lottie-ios repository को clone करने पर 300 MB से ज़्यादा डाउनलोड होता है, जबकि lottie-spm 500 KB से कम है। इससे Xcode और CI पर package resolution काफ़ी तेज़ हो जाता है।

क्या LottieView, iOS 13 या 14 पर काम करता है?

आप जो वर्ज़न पिन करते हैं, उसके लिए lottie-spm की Package.swift में platforms लिस्ट देखें, क्योंकि न्यूनतम वर्ज़न रिलीज़ के साथ बदलते हैं। LottieView खुद lottie-ios 4.3.0 में आया था। अगर आपका deployment target पैकेज में घोषित वर्ज़न से कम है, तो Xcode उस target के लिए पैकेज resolve करने से मना कर देता है।

क्या LottieView एक .lottie (dotLottie) फ़ाइल चला सकता है?

हाँ। LottieView में एक initializer है जो DotLottieFile लेता है, और एक async वैरिएंट भी है जो फ़ाइल लोड करता है और तब तक placeholder दिखाता है। dotLottie एक zip कंटेनर है जिसमें कई एनिमेशन और उनकी इमेज एक ही फ़ाइल में रह सकती हैं। यह अक्सर बराबर JSON से छोटा होता है और assets को एक साथ रखता है।

इस गाइड से झटपट जवाब

स्रोत

संबंधित गाइड