iOS ऐप में एनिमेशन कैसे जोड़ें (SwiftUI और UIKit)
Charmotion टीम द्वारा · अपडेट:

iOS ऐप में एनिमेशन जोड़ने के लिए, UI फ़ीडबैक के लिए स्टेट बदलावों को SwiftUI के withAnimation में रखें, आइकन के लिए symbolEffect इस्तेमाल करें, और डिज़ाइनर के बनाए आर्टवर्क के लिए Swift Package Manager से Lottie या Rive जोड़ें। जब कैरेक्टर को स्टेट चाहिए हों तो Rive इस्तेमाल करें, और जब सिर्फ़ एक तय क्लिप चाहिए हो तो AVPlayerLooper।
मुख्य बातें
- ज़्यादातर UI फ़ीडबैक के लिए SwiftUI का बिल्ट-इन एनिमेशन काफ़ी है:
withAnimation,.animation(_:value:), और iOS 17+ परPhaseAnimator/KeyframeAnimator। symbolEffect(iOS 17+) सिर्फ़ एक modifier से SF Symbols को एनिमेट करता है, कस्टम symbols को भी।- Lottie को
lottie-spmसे इंस्टॉल करें, 300 MB+ वाली मुख्य repository से नहीं। - Rive का
RiveRuntimeiOS 14+ सपोर्ट करता है और code से कैरेक्टर के स्टेट लाइव बदलने देता है। accessibilityReduceMotionपढ़ें, और यह चालू हो तो लूप की जगह स्थिर इमेज दिखाएँ।
पहले से कोई कैरेक्टर या लोगो है? अपने कैरेक्टर को असली ऐप स्क्रीन में देखें: स्प्लैश, ऑनबोर्डिंग, लोडिंग और एम्प्टी स्टेट स्क्रीन। यह फ़्री है, आपके ब्राउज़र में चलता है और कुछ भी अपलोड नहीं होता।
iOS पर एनिमेशन का कौन-सा तरीका इस्तेमाल करें?
शुरुआत इससे करें कि क्या मूव हो रहा है और उसे किसने बनाया है। ज़्यादातर ऐप्स को इन चार तरीकों का मिला-जुला इस्तेमाल करना पड़ता है:
| आप एनिमेट करना चाहते हैं | इस्तेमाल |
|---|---|
| बटन, लेआउट बदलाव, sheets, toggles | SwiftUI withAnimation या UIKit UIView.animate |
| आइकन | SF Symbols पर symbolEffect (iOS 17+) |
| डिज़ाइनर का बनाया वेक्टर लूप: confetti, spinner, इलस्ट्रेशन | Lottie |
| ऐप की घटनाओं पर रिएक्ट करने वाला कैरेक्टर | स्टेट मशीन के साथ Rive |
| पहले से रेंडर की गई क्लिप जो कभी नहीं बदलती | AVPlayerLooper के साथ वीडियो |
बिल्ट-इन API से ऐप का साइज़ नहीं बढ़ता और वे आपके स्टेट को अपने-आप फ़ॉलो करते हैं। ये बाकी iOS के साथ सबसे ज़्यादा मेल भी खाते हैं: springs, sheet presentations और symbol effects सब नेटिव लगते हैं, क्योंकि ये वही सिस्टम एनिमेशन हैं जो Apple के अपने ऐप्स इस्तेमाल करते हैं। थर्ड-पार्टी रनटाइम तभी लें जब आर्टवर्क किसी डिज़ाइन टूल से आए। Lottie, After Effects के एक्सपोर्ट चलाता है। Rive, Rive editor की फ़ाइलें चलाता है और इसमें स्टेट मशीन भी होती है, जिससे आपका code कैरेक्टर को idle से loading और फिर success पर ले जा सकता है, बिना क्लिप्स को जोड़े।

SwiftUI में withAnimation और .animation() कैसे काम करते हैं?
SwiftUI दो स्टेट के बीच के अंतर को एनिमेट करता है। withAnimation के अंदर कोई value बदलें, और उस पर निर्भर हर view धीरे-धीरे अपनी नई position, size या opacity में बदल जाता है:
struct ExpandingCard: View {
@State private var expanded = false
var body: some View {
RoundedRectangle(cornerRadius: 16)
.frame(height: expanded ? 240 : 120)
.onTapGesture {
withAnimation(.spring()) { expanded.toggle() }
}
}
}
दूसरा तरीका .animation(_:value:) modifier है, जो दी गई value बदलने पर हर बार view को एनिमेट करता है। जब एक action से कई views एनिमेट होने चाहिए, तब withAnimation इस्तेमाल करें, और जब एक view को हमेशा किसी खास value पर एनिमेट होना हो, तब modifier।
कई स्टेप वाले मोशन के लिए iOS 17 में PhaseAnimator और KeyframeAnimator जोड़े गए। Phase animator, phases के एक क्रम से होकर बार-बार गुज़रता है:
Image(systemName: "heart.fill")
.phaseAnimator([false, true]) { content, phase in
content.scaleEffect(phase ? 1.2 : 1.0)
}
जब scale, rotation और offset जैसी properties के लिए अलग-अलग timing tracks चाहिए हों, तब KeyframeAnimator इस्तेमाल करें। दोनों ध्यान खींचने वाले छोटे लूप के लिए अच्छे हैं, पूरे कैरेक्टर के लिए नहीं।
SF Symbols और UIKit views को एनिमेट कैसे करें?
iOS 17 और उसके बाद, .symbolEffect modifier किसी भी SF Symbol को एनिमेट करता है। Apple के बिल्ट-इन effects में bounce, pulse, variable color, scale, appear, disappear और replace शामिल हैं, और ये कस्टम symbols पर भी काम करते हैं:
Image(systemName: "bell.fill")
.symbolEffect(.bounce, value: unreadCount)
हर बार unreadCount बदलने पर घंटी उछलती है। आइकन को फ़ीडबैक देने का यह सबसे सस्ता तरीका है, क्योंकि इसमें कोई asset ship नहीं करना पड़ता।
UIKit में block-based view एनिमेशन अब भी काम करता है, और अक्सर किसी स्क्रीन को बस इतना ही चाहिए होता है:
UIView.animate(withDuration: 0.3) {
banner.alpha = 1
banner.transform = .identity
}
इसे मौजूदा views पर fade, slide और scale बदलावों के लिए इस्तेमाल करें। डिज़ाइनर की बनाई किसी भी चीज़, जैसे इलस्ट्रेशन या मैस्कॉट, के लिए Swift में keyframes हाथ से code करने पर बदलाव करना धीमा हो जाता है। यहीं Lottie या Rive फ़ाइल को मेंटेन करना आसान होता है: डिज़ाइनर फ़ाइल एडिट करता है, और आपका code सिर्फ़ तय करता है कि वह कब चले।
iOS ऐप में Lottie एनिमेशन कैसे जोड़ें?
Xcode में File > Add Package Dependencies चुनें और https://github.com/airbnb/lottie-spm.git डालें। Airbnb यही पैकेज सुझाता है, क्योंकि यह prebuilt binaries के ऊपर एक छोटा wrapper है, जबकि मुख्य lottie-ios repository 300 MB से बड़ी है। README में दिया गया latest version इस्तेमाल करें।
4.3.0 से Lottie में नेटिव SwiftUI LottieView शामिल है। एक्सपोर्ट की गई .json को अपने target में जोड़ें और चलाएँ:
import SwiftUI
import Lottie
struct ConfettiView: View {
var body: some View {
LottieView(animation: .named("confetti"))
.looping()
.frame(width: 200, height: 200)
}
}
इसी release में reduced motion का सपोर्ट भी जोड़ा गया। Lottie, loading लूप, success burst या शुरू से अंत तक चलने वाले ऑनबोर्डिंग इलस्ट्रेशन के लिए अच्छा है। यह उस कैरेक्टर के लिए कम सही है जिसे ऐप में हो रही चीज़ों के हिसाब से लूप के बीच में अपना व्यवहार बदलना हो; वहाँ Rive की स्टेट मशीन काम आती हैं।
दो काम की सलाह। एक्सपोर्ट की गई फ़ाइल छोटी रखने के लिए डिज़ाइनर से कहें कि जहाँ वेक्टर से काम चल जाए वहाँ embedded raster images न डालें। और एनिमेशन को किसी पुराने डिवाइस पर टेस्ट करें, क्योंकि After Effects के जटिल masks और effects फ़ाइल छोटी होने पर भी रेंडर करने में भारी पड़ सकते हैं।
Rive एनिमेशन कैसे जोड़ें और उसके स्टेट कैसे बदलें?
Swift Package Manager से https://github.com/rive-app/rive-ios जोड़ें (या pod 'RiveRuntime')। Apple रनटाइम iOS 14+, tvOS 16+, macOS 13.1+ और visionOS सपोर्ट करता है। .riv को अपने app target में drag करें।
Legacy API में RiveViewModel फ़ाइल लोड करता है, एक स्टेट मशीन चुनता है और उसे चलाने के लिए methods देता है:
import SwiftUI
import RiveRuntime
struct MascotView: View {
@StateObject private var mascot = RiveViewModel(
fileName: "character",
stateMachineName: "CharacterStateMachine"
)
var body: some View {
mascot.view()
.frame(width: 220, height: 220)
}
func startLoading() { mascot.setInput("mood", value: 5.0) }
func finished(ok: Bool) {
mascot.triggerInput(ok ? "success" : "error")
mascot.setInput("mood", value: 0.0)
}
}
View model को @StateObject में रखें ताकि वह redraws के बाद भी बना रहे। इनपुट के नाम case-sensitive होते हैं और फ़ाइल से मेल खाने चाहिए।
Rive का नया Apple रनटाइम इनपुट की जगह Data Binding इस्तेमाल करता है। इसमें आप view model properties सेट करते हैं, जैसे viewModelInstance.setValue(of: NumberProperty(path: "mood"), to: 5) और viewModelInstance.fire(trigger: TriggerProperty(path: "success"))। यह तभी काम करता है जब फ़ाइल में व्यू मॉडल परिभाषित हो। SwiftUI में Rive गाइड दोनों रनटाइम को विस्तार से समझाती है।
SwiftUI में वीडियो क्लिप को लूप कैसे करें?
अगर एनिमेशन एक तय, पहले से रेंडर की गई क्लिप है, जैसे 3D logo reveal, तो वीडियो किसी भी रनटाइम से आसान है। AVPlayerLooper एक AVQueuePlayer के ज़रिए item को लगातार चलाता है, और SwiftUI का VideoPlayer (AVKit, iOS 14+) उसे दिखाता है:
import SwiftUI
import AVKit
final class LoopingClip: ObservableObject {
let player = AVQueuePlayer()
private var looper: AVPlayerLooper?
init(name: String) {
guard let url = Bundle.main.url(forResource: name, withExtension: "mp4") else { return }
looper = AVPlayerLooper(player: player, templateItem: AVPlayerItem(url: url))
player.isMuted = true
player.play()
}
}
struct ClipView: View {
@StateObject private var clip = LoopingClip(name: "logo-reveal")
var body: some View { VideoPlayer(player: clip.player) }
}
Looper का reference बनाए रखें, वरना लूपिंग रुक जाती है। वीडियो स्टेट पर रिएक्ट नहीं कर सकता, और हर वैरिएशन के लिए एक अलग फ़ाइल चाहिए, इसलिए इसे क्लिप्स के लिए इस्तेमाल करें, इंटरैक्टिव कैरेक्टर के लिए नहीं।
VideoPlayer playback controls दिखाता है। बिना controls वाले सजावटी लूप के लिए, इसकी जगह एक छोटे UIViewRepresentable में AVPlayerLayer host करें। अगर क्लिप को आपके UI के ऊपर ट्रांसपेरेंट बैकग्राउंड चाहिए, तो उसे .mov में HEVC with alpha के रूप में एक्सपोर्ट करें; फ़ॉर्मेट तुलना बताती है कि यह कब GIF या Rive फ़ाइल से बेहतर है।
iOS ऐप में एनिमेटेड मैस्कॉट कैसे जोड़ें?
मैस्कॉट को अपने ऐप के स्टेट का एक view मानें। वे पल लिखें जिन पर उसे रिएक्ट करना है, फ़ाइल में हर पल के लिए एक स्टेट रखें, और अपने events को एक ही जगह उनसे जोड़ें:
- चलते रहने वाले स्टेट के लिए लूप: idle, loading, listening, sleeping।
- एक बार होने वाली घटनाओं के लिए ट्रिगर: success, error, enter पर अभिवादन।
व्यवहार में, अपने व्यू मॉडल में .idle, .loading और .done(Bool) जैसा एक छोटा enum रखें और उसे setInput और triggerInput calls में बदलें। Transitions स्टेट मशीन संभालती है, इसलिए आपको कभी ट्रैक नहीं करना पड़ता कि स्क्रीन पर कौन-सी क्लिप है।

अगर आपके पास पहले से मैस्कॉट या लोगो है पर कोई एनिमेटर नहीं, तो Charmotion अपलोड किए गए कैरेक्टर को 17 एनिमेशन में बदलता है, आमतौर पर कुछ ही मिनटों में; हर पेड प्लान पर सेट में Character व्यू मॉडल वाली एक .riv होती है (0 से 9 तक एक mood नंबर और success और error जैसे ट्रिगर), साथ में पुराने RiveViewModel और नए रनटाइम, दोनों के लिए SwiftUI कोड। सेट की प्लानिंग के लिए देखें मैस्कॉट को किन स्टेट की ज़रूरत है।
iOS एनिमेशन को तेज़ और एक्सेसिबल कैसे रखें?
कुछ आसान नियम अपनाने से एनिमेशन न ज़्यादा बैटरी खर्च करता है, न किसी यूज़र को पीछे छोड़ता है:
- एक साथ कुछ ही views एनिमेट करें, पूरी लिस्ट नहीं। जब view स्क्रीन से बाहर चला जाए, तो लूप रोक दें।
- छोटे UI आर्टवर्क के लिए वेक्टर (SF Symbols, Lottie, Rive) चुनें, और फ़ोटोग्राफ़िक या 3D क्लिप के लिए वीडियो।
- एनिमेशन फ़ाइल को पहली लॉन्च पर डाउनलोड करने के बजाय ऐप के साथ bundle करें, ताकि स्क्रीन दिखते ही वह तैयार रहे।
Settings > Accessibility > Motion > Reduce Motion सेटिंग का ध्यान रखें। SwiftUI इसे एक environment value के रूप में देता है, जो लाइव अपडेट होती है:
@Environment(\.accessibilityReduceMotion) private var reduceMotion
var body: some View {
if reduceMotion {
Image("mascot-still").resizable().scaledToFit()
} else {
mascot.view()
}
}
जब मोशन का कोई मतलब हो, जैसे loading या success, तो वही जानकारी टेक्स्ट या एक्सेसिबिलिटी announcement के रूप में भी उपलब्ध रखें। मोशन कम करने वाली गाइड में WCAG के नियम दिए गए हैं।
iOS ऐप में एनिमेशन जोड़ें
- SwiftUI से शुरू करें. UI फ़ीडबैक के लिए
withAnimationया.animation(_:value:)और आइकन के लिएsymbolEffectइस्तेमाल करें। - ज़रूरत हो तो रनटाइम जोड़ें. Xcode में Lottie के लिए
https://github.com/airbnb/lottie-spm.gitया Rive के लिएhttps://github.com/rive-app/rive-iosजोड़ें। - फ़ाइल bundle करें.
.json,.rivया.mp4फ़ाइल को project में ड्रैग करें और पक्का करें कि वह app target का member है। - इसे दिखाएँ.
LottieView(animation: .named("name")).looping(),RiveViewModel(fileName:stateMachineName:).view()याVideoPlayerइस्तेमाल करें। - इसे ऐप की स्टेट से जोड़ें. जब आपका व्यू मॉडल बदले, तो लूप के लिए
setInputऔर वन-शॉट के लिएtriggerInputकॉल करें। - Reduce Motion सेटिंग का ध्यान रखें.
accessibilityReduceMotionपढ़ें और इसके true होने पर एक स्थिर इमेज दिखाएँ।
अक्सर पूछे जाने वाले सवाल
UIView.animate इस्तेमाल करूँ या withAnimation?
SwiftUI views में withAnimation और UIKit views में UIView.animate इस्तेमाल करें। दोनों मौजूदा views में property के बदलाव को एनिमेट करते हैं। SwiftUI का तरीका उन सभी views को एनिमेट करता है जो बदली हुई स्टेट पर निर्भर हैं, इसलिए आप हर view का frame बताने के बजाय सिर्फ़ अंतिम स्टेट बताते हैं। मिले-जुले ऐप दोनों का इस्तेमाल कर सकते हैं, हर एक अपनी layer में।
PhaseAnimator और KeyframeAnimator में क्या अंतर है?
दोनों iOS 17 में आए। PhaseAnimator phases की एक लिस्ट से होकर गुज़रता है और उनके बीच एनिमेट करता है, जो सरल pulse और कई स्टेप वाले sequence के लिए ठीक है। KeyframeAnimator हर property को keyframes की अपनी अलग timeline देता है, जो ऐसे सटीक मोशन के लिए ठीक है जिसमें scale, rotation और position अलग-अलग समय पर बदलते हैं।
iOS ऐप के लिए Lottie या Rive?
After Effects से एक्सपोर्ट किए गए, डिज़ाइनर के बनाए linear वेक्टर लूप के लिए Lottie इस्तेमाल करें। जब एनिमेशन को ऐप की स्टेट पर रिएक्ट करना हो, जैसे कोई मैस्कॉट idle, loading और success के बीच बदले, तब Rive इस्तेमाल करें, क्योंकि उसकी स्टेट मशीन फ़ाइल के अंदर ही transitions संभालती है। दोनों Swift Package Manager से install होते हैं और SwiftUI में काम करते हैं।
क्या Rive UIKit के साथ काम करता है?
हाँ। RiveRuntime SwiftUI और UIKit दोनों को सपोर्ट करता है। Legacy रनटाइम में RiveViewModel SwiftUI view के साथ-साथ UIKit view भी बना सकता है, और वही setInput और triggerInput कॉल उसे कंट्रोल करते हैं। Rive के Apple documentation में दोनों setup दिए गए हैं, इसलिए आप एक ही ऐप में दोनों मिला सकते हैं।
इस गाइड से झटपट जवाब
स्रोत
- withAnimation(_:_:), Apple
- Wind your way through advanced animations in SwiftUI (WWDC23), WWDC Notes
- Animate symbols in your app (WWDC23), Apple
- lottie-ios, Airbnb (GitHub)
- lottie-ios 4.3.0 release notes, Airbnb (GitHub)
- Apple runtime, Rive
- AVPlayerLooper, Apple
- accessibilityReduceMotion, Apple