lottie-ios 4.4.2 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/.github/workflows/main.yml +12 -39
  2. package/Lottie.xcodeproj/project.pbxproj +28 -0
  3. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  4. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +19 -6
  5. package/Package.resolved +2 -2
  6. package/Package.swift +1 -1
  7. package/README.md +2 -2
  8. package/Rakefile +1 -1
  9. package/Sources/PrivacyInfo.xcprivacy +1 -1
  10. package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +2 -2
  11. package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +6 -6
  12. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +24 -9
  13. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +2 -2
  14. package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +7 -7
  15. package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +12 -12
  16. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +19 -19
  17. package/Sources/Private/CoreAnimation/ValueProviderStore.swift +4 -4
  18. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +13 -6
  19. package/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift +3 -3
  20. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+BackingConfiguration.swift +10 -6
  21. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift +4 -0
  22. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Progress.swift +2 -2
  23. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Reading.swift +5 -0
  24. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Writing.swift +2 -0
  25. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Compression.swift +1 -0
  26. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry+ZIP64.swift +2 -2
  27. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry.swift +1 -0
  28. package/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift +10 -9
  29. package/Sources/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.swift +19 -0
  30. package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +7 -7
  31. package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +3 -0
  32. package/Sources/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.swift +24 -14
  33. package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +11 -10
  34. package/Sources/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.swift +2 -0
  35. package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +102 -17
  36. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +11 -11
  37. package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +2 -0
  38. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/LayerEffectNodes/DropShadowNode.swift +102 -0
  39. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/LayerEffectNodes/LayerEffectNode.swift +24 -0
  40. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +4 -4
  41. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +16 -16
  42. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +4 -4
  43. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +5 -5
  44. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +60 -1
  45. package/Sources/Private/Model/DotLottie/DotLottieAnimation.swift +2 -2
  46. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +9 -6
  47. package/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift +4 -4
  48. package/Sources/Private/Model/LayerEffects/LayerEffect.swift +2 -2
  49. package/Sources/Private/Model/LayerStyles/LayerStyle.swift +2 -2
  50. package/Sources/Private/Model/Layers/LayerModel.swift +7 -7
  51. package/Sources/Private/Model/ShapeItems/ShapeItem.swift +15 -15
  52. package/Sources/Private/Model/Text/TextAnimator.swift +47 -1
  53. package/Sources/Private/Utility/Debugging/LayerDebugging.swift +6 -6
  54. package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +16 -16
  55. package/Sources/Private/Utility/Extensions/BlendMode+Filter.swift +16 -16
  56. package/Sources/Private/Utility/Extensions/CGColor+RGB.swift +18 -0
  57. package/Sources/Private/Utility/Extensions/CGFloatExtensions.swift +23 -23
  58. package/Sources/Private/Utility/Extensions/MathKit.swift +4 -11
  59. package/Sources/Private/Utility/Interpolatable/InterpolatableExtensions.swift +9 -3
  60. package/Sources/Private/Utility/LottieAnimationSource.swift +4 -4
  61. package/Sources/Private/Utility/Primitives/BezierPath.swift +16 -2
  62. package/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift +2 -2
  63. package/Sources/Private/Utility/Primitives/ColorExtension.swift +20 -20
  64. package/Sources/Private/Utility/Primitives/CompoundBezierPath.swift +9 -9
  65. package/Sources/Public/Animation/LottieAnimationLayer.swift +36 -31
  66. package/Sources/Public/Animation/LottieAnimationView.swift +15 -15
  67. package/Sources/Public/Animation/LottieAnimationViewInitializers.swift +4 -0
  68. package/Sources/Public/Animation/LottiePlaybackMode.swift +12 -12
  69. package/Sources/Public/Animation/LottieView.swift +53 -5
  70. package/Sources/Public/Configuration/ReducedMotionOption.swift +5 -5
  71. package/Sources/Public/Configuration/RenderingEngineOption.swift +4 -4
  72. package/Sources/Public/Controls/AnimatedSwitch.swift +2 -2
  73. package/Sources/Public/DotLottie/DotLottieFile.swift +2 -2
  74. package/Sources/Public/DynamicProperties/AnyValueProvider.swift +9 -9
  75. package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +2 -2
  76. package/Sources/Public/Keyframes/Interpolatable.swift +2 -2
  77. package/Sources/Public/Primitives/LottieColor.swift +3 -3
  78. package/Sources/Public/TextProvider/AnimationTextProvider.swift +4 -4
  79. package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +13 -12
  80. package/Version.xcconfig +2 -2
  81. package/lottie-ios.podspec +2 -2
  82. package/package.json +1 -1
@@ -43,9 +43,9 @@ public enum LottieBackgroundBehavior {
43
43
  public static func `default`(for renderingEngine: RenderingEngine) -> LottieBackgroundBehavior {
44
44
  switch renderingEngine {
45
45
  case .mainThread:
46
- return .pauseAndRestore
46
+ .pauseAndRestore
47
47
  case .coreAnimation:
48
- return .continuePlaying
48
+ .continuePlaying
49
49
  }
50
50
  }
51
51
  }
@@ -73,13 +73,13 @@ extension LottieLoopMode: Equatable {
73
73
  switch (lhs, rhs) {
74
74
  case (.repeat(let lhsAmount), .repeat(let rhsAmount)),
75
75
  (.repeatBackwards(let lhsAmount), .repeatBackwards(let rhsAmount)):
76
- return lhsAmount == rhsAmount
76
+ lhsAmount == rhsAmount
77
77
  case (.playOnce, .playOnce),
78
78
  (.loop, .loop),
79
79
  (.autoReverse, .autoReverse):
80
- return true
80
+ true
81
81
  default:
82
- return false
82
+ false
83
83
  }
84
84
  }
85
85
  }
@@ -567,9 +567,9 @@ open class LottieAnimationView: LottieAnimationViewBase {
567
567
  // duration and curve are captured and added to the layer. This is used in the
568
568
  // layout block to animate the animationLayer's position and size.
569
569
  let rect = bounds
570
- self.bounds = CGRect.zero
571
- self.bounds = rect
572
- self.setNeedsLayout()
570
+ bounds = CGRect.zero
571
+ bounds = rect
572
+ setNeedsLayout()
573
573
  }
574
574
  }
575
575
 
@@ -813,7 +813,7 @@ open class LottieAnimationView: LottieAnimationViewBase {
813
813
 
814
814
  // MARK: Internal
815
815
 
816
- // The backing CALayer for this animation view.
816
+ /// The backing CALayer for this animation view.
817
817
  let lottieAnimationLayer: LottieAnimationLayer
818
818
 
819
819
  var animationLayer: RootAnimationLayer? {
@@ -823,7 +823,7 @@ open class LottieAnimationView: LottieAnimationViewBase {
823
823
  /// Set animation name from Interface Builder
824
824
  @IBInspectable var animationName: String? {
825
825
  didSet {
826
- self.lottieAnimationLayer.animation = animationName.flatMap { LottieAnimation.named($0, animationCache: nil)
826
+ lottieAnimationLayer.animation = animationName.flatMap { LottieAnimation.named($0, animationCache: nil)
827
827
  }
828
828
  }
829
829
  }
@@ -835,15 +835,15 @@ open class LottieAnimationView: LottieAnimationViewBase {
835
835
 
836
836
  lottieAnimationLayer.animationLoaded = { [weak self] _, animation in
837
837
  guard let self else { return }
838
- self.animationLoaded?(self, animation)
839
- self.invalidateIntrinsicContentSize()
840
- self.setNeedsLayout()
838
+ animationLoaded?(self, animation)
839
+ invalidateIntrinsicContentSize()
840
+ setNeedsLayout()
841
841
  }
842
842
 
843
843
  lottieAnimationLayer.animationLayerDidLoad = { [weak self] _, _ in
844
844
  guard let self else { return }
845
- self.invalidateIntrinsicContentSize()
846
- self.setNeedsLayout()
845
+ invalidateIntrinsicContentSize()
846
+ setNeedsLayout()
847
847
  }
848
848
  }
849
849
 
@@ -122,6 +122,7 @@ extension LottieAnimationView {
122
122
  case .success(let dotLottieFile):
123
123
  self.loadAnimation(animationId, from: dotLottieFile)
124
124
  completion?(self, nil)
125
+
125
126
  case .failure(let error):
126
127
  completion?(self, error)
127
128
  }
@@ -147,6 +148,7 @@ extension LottieAnimationView {
147
148
  case .success(let dotLottieFile):
148
149
  self.loadAnimation(animationId, from: dotLottieFile)
149
150
  completion?(self, nil)
151
+
150
152
  case .failure(let error):
151
153
  completion?(self, error)
152
154
  }
@@ -176,6 +178,7 @@ extension LottieAnimationView {
176
178
  case .success(let lottie):
177
179
  self.loadAnimation(animationId, from: lottie)
178
180
  completion?(self, nil)
181
+
179
182
  case .failure(let error):
180
183
  completion?(self, error)
181
184
  }
@@ -203,6 +206,7 @@ extension LottieAnimationView {
203
206
  case .success(let dotLottieFile):
204
207
  self.loadAnimation(animationId, from: dotLottieFile)
205
208
  completion?(self, nil)
209
+
206
210
  case .failure(let error):
207
211
  completion?(self, error)
208
212
  }
@@ -170,7 +170,7 @@ extension LottiePlaybackMode.PlaybackMode {
170
170
  .fromProgress(nil, toProgress: toProgress, loopMode: loopMode)
171
171
  }
172
172
 
173
- // Plays the animation from the current frame to the given frame.
173
+ /// Plays the animation from the current frame to the given frame.
174
174
  /// - Parameter toFrame: The end frame of the animation.
175
175
  /// - Parameter loopMode: The loop behavior of the animation.
176
176
  public static func toFrame(_ toFrame: AnimationFrameTime, loopMode: LottieLoopMode) -> Self {
@@ -211,32 +211,32 @@ extension LottiePlaybackMode {
211
211
  func loopMode(_ updatedLoopMode: LottieLoopMode) -> LottiePlaybackMode {
212
212
  switch self {
213
213
  case .playing(let playbackMode):
214
- return .playing(playbackMode.loopMode(updatedLoopMode))
214
+ .playing(playbackMode.loopMode(updatedLoopMode))
215
215
 
216
216
  case .fromProgress(let fromProgress, toProgress: let toProgress, _):
217
- return .playing(.fromProgress(
217
+ .playing(.fromProgress(
218
218
  fromProgress,
219
219
  toProgress: toProgress,
220
220
  loopMode: updatedLoopMode))
221
221
 
222
222
  case .fromFrame(let fromFrame, toFrame: let toFrame, _):
223
- return .playing(.fromFrame(
223
+ .playing(.fromFrame(
224
224
  fromFrame,
225
225
  toFrame: toFrame,
226
226
  loopMode: updatedLoopMode))
227
227
 
228
228
  case .fromMarker(let fromMarker, let toMarker, let playEndMarkerFrame, _):
229
- return .playing(.fromMarker(
229
+ .playing(.fromMarker(
230
230
  fromMarker,
231
231
  toMarker: toMarker,
232
232
  playEndMarkerFrame: playEndMarkerFrame,
233
233
  loopMode: updatedLoopMode))
234
234
 
235
235
  case .marker(let marker, _):
236
- return .playing(.marker(marker, loopMode: updatedLoopMode))
236
+ .playing(.marker(marker, loopMode: updatedLoopMode))
237
237
 
238
238
  case .pause, .paused, .progress(_), .time(_), .frame(_), .markers:
239
- return self
239
+ self
240
240
  }
241
241
  }
242
242
  }
@@ -246,15 +246,15 @@ extension LottiePlaybackMode.PlaybackMode {
246
246
  func loopMode(_ updatedLoopMode: LottieLoopMode) -> LottiePlaybackMode.PlaybackMode {
247
247
  switch self {
248
248
  case .fromProgress(let fromProgress, let toProgress, _):
249
- return .fromProgress(fromProgress, toProgress: toProgress, loopMode: updatedLoopMode)
249
+ .fromProgress(fromProgress, toProgress: toProgress, loopMode: updatedLoopMode)
250
250
  case .fromFrame(let fromFrame, let toFrame, _):
251
- return .fromFrame(fromFrame, toFrame: toFrame, loopMode: updatedLoopMode)
251
+ .fromFrame(fromFrame, toFrame: toFrame, loopMode: updatedLoopMode)
252
252
  case .fromMarker(let fromMarker, let toMarker, let playEndMarkerFrame, _):
253
- return .fromMarker(fromMarker, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: updatedLoopMode)
253
+ .fromMarker(fromMarker, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: updatedLoopMode)
254
254
  case .marker(let marker, _):
255
- return .marker(marker, loopMode: updatedLoopMode)
255
+ .marker(marker, loopMode: updatedLoopMode)
256
256
  case .markers:
257
- return self
257
+ self
258
258
  }
259
259
  }
260
260
  }
@@ -125,7 +125,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
125
125
  }
126
126
  .sizing(sizing)
127
127
  .configure { context in
128
- applyCurrentAnimationConfiguration(to: context.view)
128
+ applyCurrentAnimationConfiguration(to: context.view, in: context.container)
129
129
  }
130
130
  .configurations(configurations)
131
131
  .opacity(animationSource == nil ? 0 : 1)
@@ -141,9 +141,42 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
141
141
  }
142
142
  }
143
143
 
144
+ /// Returns a copy of this `LottieView` updated to have the specific configuration property
145
+ /// applied to its represented `LottieAnimationView` whenever it is updated via the `updateUIView(...)`
146
+ /// or `updateNSView(...)` methods.
147
+ ///
148
+ /// - note: This configuration will be applied on every SwiftUI render pass.
149
+ /// Be wary of applying heavy side-effects as configuration values.
150
+ public func configure<Property>(
151
+ _ property: ReferenceWritableKeyPath<LottieAnimationView, Property>,
152
+ to value: Property)
153
+ -> Self
154
+ {
155
+ configure { $0[keyPath: property] = value }
156
+ }
157
+
158
+ /// Returns a copy of this `LottieView` updated to have the specific configuration property
159
+ /// applied to its represented `LottieAnimationView` whenever it is updated via the `updateUIView(...)`
160
+ /// or `updateNSView(...)` methods.
161
+ ///
162
+ /// - note: If the `value` is already the currently-applied configuration value, it won't be applied
163
+ public func configure<Property: Equatable>(
164
+ _ property: ReferenceWritableKeyPath<LottieAnimationView, Property>,
165
+ to value: Property)
166
+ -> Self
167
+ {
168
+ configure {
169
+ guard $0[keyPath: property] != value else { return }
170
+ $0[keyPath: property] = value
171
+ }
172
+ }
173
+
144
174
  /// Returns a copy of this `LottieView` updated to have the given closure applied to its
145
175
  /// represented `LottieAnimationView` whenever it is updated via the `updateUIView(…)`
146
176
  /// or `updateNSView(…)` method.
177
+ ///
178
+ /// - note: This configuration closure will be executed on every SwiftUI render pass.
179
+ /// Be wary of applying heavy side-effects inside it.
147
180
  public func configure(_ configure: @escaping (LottieAnimationView) -> Void) -> Self {
148
181
  var copy = self
149
182
  copy.configurations.append { context in
@@ -152,14 +185,22 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
152
185
  return copy
153
186
  }
154
187
 
155
- /// Returns a copy of this view that can be resized by scaling its animation to fit the size
156
- /// offered by its parent.
188
+ /// Returns a copy of this view that can be resized by scaling its animation
189
+ /// to always fit the size offered by its parent.
157
190
  public func resizable() -> Self {
158
191
  var copy = self
159
192
  copy.sizing = .proposed
160
193
  return copy
161
194
  }
162
195
 
196
+ /// Returns a copy of this view that adopts the intrinsic size of the animation,
197
+ /// up to the proposed size.
198
+ public func intrinsicSize() -> Self {
199
+ var copy = self
200
+ copy.sizing = .intrinsic
201
+ return copy
202
+ }
203
+
163
204
  @available(*, deprecated, renamed: "playing()", message: "Will be removed in a future major release.")
164
205
  public func play() -> Self {
165
206
  playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce)))
@@ -191,7 +232,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
191
232
  playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: loopMode)))
192
233
  }
193
234
 
194
- // Returns a copy of this view playing once from the current frame to the end frame
235
+ /// Returns a copy of this view playing once from the current frame to the end frame
195
236
  public func playing() -> Self {
196
237
  playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce)))
197
238
  }
@@ -501,7 +542,10 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
501
542
  }
502
543
 
503
544
  /// Applies playback configuration for the current animation to the `LottieAnimationView`
504
- private func applyCurrentAnimationConfiguration(to view: LottieAnimationView) {
545
+ private func applyCurrentAnimationConfiguration(
546
+ to view: LottieAnimationView,
547
+ in container: SwiftUIMeasurementContainer<LottieAnimationView>)
548
+ {
505
549
  guard let animationSource else { return }
506
550
  var imageProviderConfiguration = imageProviderConfiguration
507
551
  var playbackMode = playbackMode
@@ -543,6 +587,10 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
543
587
  if animationSource.animation !== view.animation {
544
588
  view.loadAnimation(animationSource)
545
589
  animationDidLoad?(animationSource)
590
+
591
+ // Invalidate the intrinsic size of the SwiftUI measurement container,
592
+ // since any cached measurements will be out of date after updating the animation.
593
+ container.invalidateIntrinsicContentSize()
546
594
  }
547
595
 
548
596
  if
@@ -43,9 +43,9 @@ extension ReducedMotionOption {
43
43
  public var currentReducedMotionMode: ReducedMotionMode {
44
44
  switch self {
45
45
  case .specific(let specificMode):
46
- return specificMode
46
+ specificMode
47
47
  case .dynamic(let optionProvider, _):
48
- return optionProvider.currentReducedMotionMode
48
+ optionProvider.currentReducedMotionMode
49
49
  }
50
50
  }
51
51
  }
@@ -56,11 +56,11 @@ extension ReducedMotionOption: Hashable {
56
56
  public static func ==(_ lhs: ReducedMotionOption, _ rhs: ReducedMotionOption) -> Bool {
57
57
  switch (lhs, rhs) {
58
58
  case (.specific(let lhsMode), .specific(let rhsMode)):
59
- return lhsMode == rhsMode
59
+ lhsMode == rhsMode
60
60
  case (.dynamic(_, let lhsDataID), .dynamic(_, dataID: let rhsDataID)):
61
- return lhsDataID == rhsDataID
61
+ lhsDataID == rhsDataID
62
62
  case (.dynamic, .specific), (.specific, .dynamic):
63
- return false
63
+ false
64
64
  }
65
65
  }
66
66
 
@@ -67,9 +67,9 @@ extension RenderingEngineOption: RawRepresentable, CustomStringConvertible {
67
67
  public var rawValue: String {
68
68
  switch self {
69
69
  case .automatic:
70
- return "Automatic"
70
+ "Automatic"
71
71
  case .specific(let engine):
72
- return engine.rawValue
72
+ engine.rawValue
73
73
  }
74
74
  }
75
75
 
@@ -101,9 +101,9 @@ extension RenderingEngine: RawRepresentable, CustomStringConvertible {
101
101
  public var rawValue: String {
102
102
  switch self {
103
103
  case .mainThread:
104
- return "Main Thread"
104
+ "Main Thread"
105
105
  case .coreAnimation:
106
- return "Core Animation"
106
+ "Core Animation"
107
107
  }
108
108
  }
109
109
 
@@ -213,8 +213,8 @@ open class AnimatedSwitch: AnimatedControl {
213
213
 
214
214
  // For the Main Thread rendering engine, we freeze the animation at the expected final progress
215
215
  // once the animation is complete. This isn't necessary on the Core Animation engine.
216
- if finished, !(self.animationView.animationLayer is CoreAnimationLayer) {
217
- self.animationView.currentProgress = finalProgress
216
+ if finished, !(animationView.animationLayer is CoreAnimationLayer) {
217
+ animationView.currentProgress = finalProgress
218
218
  }
219
219
  })
220
220
  }
@@ -56,9 +56,9 @@ public final class DotLottieFile {
56
56
  /// The `LottieAnimation` and `DotLottieConfiguration` for the given animation ID in this file
57
57
  func animation(for id: String? = nil) -> DotLottieFile.Animation? {
58
58
  if let id {
59
- return animations.first(where: { $0.configuration.id == id })
59
+ animations.first(where: { $0.configuration.id == id })
60
60
  } else {
61
- return animations.first
61
+ animations.first
62
62
  }
63
63
  }
64
64
 
@@ -49,13 +49,13 @@ extension ValueProvider {
49
49
  public var typeErasedStorage: AnyValueProviderStorage {
50
50
  switch storage {
51
51
  case .closure(let typedClosure):
52
- return .closure(typedClosure)
52
+ .closure(typedClosure)
53
53
 
54
54
  case .singleValue(let typedValue):
55
- return .singleValue(typedValue)
55
+ .singleValue(typedValue)
56
56
 
57
57
  case .keyframes(let keyframes):
58
- return .keyframes(
58
+ .keyframes(
59
59
  keyframes.map { keyframe in
60
60
  keyframe.withValue(keyframe.value as Any)
61
61
  },
@@ -88,13 +88,13 @@ public enum ValueProviderStorage<T: AnyInterpolatable> {
88
88
  func value(frame: AnimationFrameTime) -> T {
89
89
  switch self {
90
90
  case .singleValue(let value):
91
- return value
91
+ value
92
92
 
93
93
  case .closure(let closure):
94
- return closure(frame)
94
+ closure(frame)
95
95
 
96
96
  case .keyframes(let keyframes):
97
- return KeyframeInterpolator(keyframes: ContiguousArray(keyframes)).storage.value(frame: frame)
97
+ KeyframeInterpolator(keyframes: ContiguousArray(keyframes)).storage.value(frame: frame)
98
98
  }
99
99
  }
100
100
  }
@@ -119,13 +119,13 @@ public enum AnyValueProviderStorage {
119
119
  func value(frame: AnimationFrameTime) -> Any {
120
120
  switch self {
121
121
  case .singleValue(let value):
122
- return value
122
+ value
123
123
 
124
124
  case .closure(let closure):
125
- return closure(frame)
125
+ closure(frame)
126
126
 
127
127
  case .keyframes(_, let valueForFrame):
128
- return valueForFrame(frame)
128
+ valueForFrame(frame)
129
129
  }
130
130
  }
131
131
  }
@@ -70,7 +70,7 @@ public final class GradientValueProvider: ValueProvider {
70
70
 
71
71
  public var storage: ValueProviderStorage<[Double]> {
72
72
  if let block {
73
- return .closure { [self] frame in
73
+ .closure { [self] frame in
74
74
  hasUpdate = false
75
75
 
76
76
  let newColors = block(frame)
@@ -80,7 +80,7 @@ public final class GradientValueProvider: ValueProvider {
80
80
  return value
81
81
  }
82
82
  } else {
83
- return .singleValue(value)
83
+ .singleValue(value)
84
84
  }
85
85
  }
86
86
 
@@ -271,9 +271,9 @@ struct Hold<T>: Interpolatable {
271
271
 
272
272
  func interpolate(to: Hold<T>, amount: CGFloat) -> Hold<T> {
273
273
  if amount < 1 {
274
- return self
274
+ self
275
275
  } else {
276
- return to
276
+ to
277
277
  }
278
278
  }
279
279
  }
@@ -15,11 +15,11 @@ public enum ColorFormatDenominator: Hashable {
15
15
  var value: Double {
16
16
  switch self {
17
17
  case .One:
18
- return 1.0
18
+ 1.0
19
19
  case .OneHundred:
20
- return 100.0
20
+ 100.0
21
21
  case .TwoFiftyFive:
22
- return 255.0
22
+ 255.0
23
23
  }
24
24
  }
25
25
  }
@@ -62,22 +62,22 @@ public final class DictionaryTextProvider: AnimationKeypathTextProvider, LegacyA
62
62
 
63
63
  public func text(for keypath: AnimationKeypath, sourceText: String) -> String? {
64
64
  if let valueForFullKeypath = values[keypath.fullPath] {
65
- return valueForFullKeypath
65
+ valueForFullKeypath
66
66
  }
67
67
 
68
68
  else if
69
69
  let lastKeypathComponent = keypath.keys.last,
70
70
  let valueForLastComponent = values[lastKeypathComponent]
71
71
  {
72
- return valueForLastComponent
72
+ valueForLastComponent
73
73
  }
74
74
 
75
75
  else {
76
- return sourceText
76
+ sourceText
77
77
  }
78
78
  }
79
79
 
80
- // Never called directly by Lottie, but we continue to implement this conformance for backwards compatibility.
80
+ /// Never called directly by Lottie, but we continue to implement this conformance for backwards compatibility.
81
81
  public func textFor(keypathName: String, sourceText: String) -> String {
82
82
  values[keypathName] ?? sourceText
83
83
  }
@@ -77,15 +77,15 @@ public enum CompatibleRenderingEngineOption: Int {
77
77
  {
78
78
  switch configuration {
79
79
  case .shared:
80
- return LottieConfiguration.shared
80
+ LottieConfiguration.shared
81
81
  case .defaultEngine:
82
- return LottieConfiguration(renderingEngine: .coreAnimation)
82
+ LottieConfiguration(renderingEngine: .coreAnimation)
83
83
  case .automatic:
84
- return LottieConfiguration(renderingEngine: .automatic)
84
+ LottieConfiguration(renderingEngine: .automatic)
85
85
  case .mainThread:
86
- return LottieConfiguration(renderingEngine: .mainThread)
86
+ LottieConfiguration(renderingEngine: .mainThread)
87
87
  case .coreAnimation:
88
- return LottieConfiguration(renderingEngine: .coreAnimation)
88
+ LottieConfiguration(renderingEngine: .coreAnimation)
89
89
  }
90
90
  }
91
91
  }
@@ -219,7 +219,8 @@ public final class CompatibleAnimationView: UIView {
219
219
  }
220
220
  }
221
221
 
222
- @objc public override var contentMode: UIView.ContentMode {
222
+ @objc
223
+ public override var contentMode: UIView.ContentMode {
223
224
  set { animationView.contentMode = newValue }
224
225
  get { animationView.contentMode }
225
226
  }
@@ -285,15 +286,15 @@ public final class CompatibleAnimationView: UIView {
285
286
  get {
286
287
  switch animationView.backgroundBehavior {
287
288
  case .stop:
288
- return .stop
289
+ .stop
289
290
  case .pause:
290
- return .pause
291
+ .pause
291
292
  case .pauseAndRestore:
292
- return .pauseAndRestore
293
+ .pauseAndRestore
293
294
  case .forceFinish:
294
- return .forceFinish
295
+ .forceFinish
295
296
  case .continuePlaying:
296
- return .continuePlaying
297
+ .continuePlaying
297
298
  }
298
299
  }
299
300
  set {
@@ -440,7 +441,7 @@ public final class CompatibleAnimationView: UIView {
440
441
  public func getColorValue(for keypath: CompatibleAnimationKeypath, atFrame: CGFloat) -> UIColor? {
441
442
  let value = animationView.getValue(for: keypath.animationKeypath, atFrame: atFrame)
442
443
  guard let colorValue = value as? LottieColor else {
443
- return nil;
444
+ return nil
444
445
  }
445
446
 
446
447
  return UIColor(
package/Version.xcconfig CHANGED
@@ -2,5 +2,5 @@
2
2
  // Copyright © 2024 Airbnb Inc. All rights reserved.
3
3
 
4
4
  // The version numbers used when building Lottie.xcframework
5
- MARKETING_VERSION = 4.4.2
6
- CURRENT_PROJECT_VERSION = 442 // a three-digit representation of the marketing version, without dots.
5
+ MARKETING_VERSION = 4.5.0
6
+ CURRENT_PROJECT_VERSION = 443 // a three-digit representation of the marketing version, without dots.
@@ -8,7 +8,7 @@
8
8
 
9
9
  Pod::Spec.new do |s|
10
10
  s.name = 'lottie-ios'
11
- s.version = '4.4.2'
11
+ s.version = '4.5.0'
12
12
  s.summary = 'A library to render native animations from bodymovin json'
13
13
 
14
14
  s.description = <<-DESC
@@ -22,7 +22,7 @@ Lottie enables designers to create and ship beautiful animations without an engi
22
22
  s.author = { 'Brandon Withrow' => 'buba447@gmail.com', 'Cal Stephens' => 'cal.stephens@airbnb.com' }
23
23
  s.source = { :git => 'https://github.com/airbnb/lottie-ios.git', :tag => s.version.to_s }
24
24
 
25
- s.swift_version = '5.7'
25
+ s.swift_version = '5.9'
26
26
  s.ios.deployment_target = '13.0'
27
27
  s.osx.deployment_target = '10.15'
28
28
  s.tvos.deployment_target = '13.0'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lottie-ios",
3
- "version": "4.4.2",
3
+ "version": "4.5.0",
4
4
  "description": "Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with bodymovin and renders the vector animations natively on mobile and through React Native!",
5
5
  "main": "index.js",
6
6
  "scripts": {