lottie-ios 3.4.3 → 3.4.4

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 (45) hide show
  1. package/.github/FUNDING.yml +0 -11
  2. package/Lottie.xcodeproj/project.pbxproj +2 -2
  3. package/Lottie.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +22 -0
  4. package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +2 -2
  5. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  6. package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +10 -7
  7. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +1 -1
  8. package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +1 -1
  9. package/Sources/Private/Model/Objects/Marker.swift +4 -0
  10. package/Sources/Public/Animation/AnimationPublic.swift +15 -0
  11. package/Sources/Public/Animation/AnimationView.swift +41 -0
  12. package/Sources/Public/iOS/AnimatedButton.swift +25 -23
  13. package/Sources/Public/iOS/AnimatedSwitch.swift +15 -10
  14. package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +15 -0
  15. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +1 -0
  16. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~7IO4FqH8-VUsSfuA0_wMGUgfGdV7MwzpkzjwWbiB50jXZKQRHtU4G0A7ZXTvsR4mDdrWiawpNC_eriOALfZ7Og== +0 -0
  17. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~ClRW5-6rvrgZHHbrPS1VEREaxelpVcKlERPzSa3f2rtFNXdoqATxFCsPge3a_nO4mhhtpmTmbYvyfI-obAu8Qg== +0 -0
  18. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~Jr2dFGcJc1188nMoMha82z9wM99lCLm4MKzhjfVVjIxKeCZVGWGZH3HgJFNkTpozdk5p1u5o91dCiY4-cR1Zhg== +0 -0
  19. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~MBDeCFoahVzzmtSQrVhhy9VMJV6CmcnUkFya_qwe0XsMFscmY2nS8dxrTEYkY16sH68sEH7WVCCzTuW1z1Hocw== +1 -0
  20. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw== +0 -0
  21. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~UsLY5O-vDMEHEe3bF8XJvkKkYxdsKlIytgJW7zgNuetw53fG3SssfZiiMfbuYnOtvvvYBXTwpbz07V6Czp029Q== +0 -0
  22. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cpg4cb7H0TaehHy4a-xINJMFfBM2_AEHal_0tIX8ymNVJPsjlCysi3-Cad0Ca_SvuGwVM7ONF55OBUuC9YKZvA== +0 -0
  23. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~cuHjdTCuciVumvEpvozxwDj2wAdgWe13bzd1pUAGN45-WOgY0kIid9aUlBX675OnS-xNEc_pyQWo0RO1dKAjcw== +0 -0
  24. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~f_-bfn-KRHHFg39_MtwgBulEAuWH6F05yqGYydXhil6kqZ51eAoRX6tsiqOr0Oa6eL3dK1tcCBD1bWX5orCZhw== +1 -0
  25. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~jdIx7vWS6ej1cqYcbCS4KyZErSMF13ELR95YwClVc98tIXcsglh7KuGvI1gIxEPDtPXQpfC3XijIAGn1quL8Dw== +0 -0
  26. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~lz3e0YeBa8TvMBSSymToh--gc6zznUIdH2jO0AJ4so5OPNdw6wpYmJebhaENGsRoD3beUXvlyD5f7_WeZrzyNQ== +0 -0
  27. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~u_5dWbliYJ__YkyUCDFjdxiFds9M8Epr_RvbU1rIRCbBQdhRJ_TUBXXcL_Qq-wVp4umNLTOzud4OpQItSpO6Rg== +0 -0
  28. package/Tests/Artifacts/LottieTests.xcresult/Data/data.0~v-YGzhC2l_icsAsyp1XAbEWYwxNook-rARAWlVZINioEsgT9LGvhg2oh78nYqoeH78m1fihr5HCcGNfF7SQj0g== +0 -0
  29. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~4VqMqsI5lOfxRppnud6-VDWcNsU8J7VgFCJfW2dXPwOcAkvU-I8Um5yp9n0Zv6nr3VmcxYggaVMDFfR0U_vjKw== +0 -0
  30. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~7IO4FqH8-VUsSfuA0_wMGUgfGdV7MwzpkzjwWbiB50jXZKQRHtU4G0A7ZXTvsR4mDdrWiawpNC_eriOALfZ7Og== +0 -0
  31. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~ClRW5-6rvrgZHHbrPS1VEREaxelpVcKlERPzSa3f2rtFNXdoqATxFCsPge3a_nO4mhhtpmTmbYvyfI-obAu8Qg== +0 -0
  32. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~Jr2dFGcJc1188nMoMha82z9wM99lCLm4MKzhjfVVjIxKeCZVGWGZH3HgJFNkTpozdk5p1u5o91dCiY4-cR1Zhg== +0 -0
  33. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~MBDeCFoahVzzmtSQrVhhy9VMJV6CmcnUkFya_qwe0XsMFscmY2nS8dxrTEYkY16sH68sEH7WVCCzTuW1z1Hocw== +0 -0
  34. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw== +0 -0
  35. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~UsLY5O-vDMEHEe3bF8XJvkKkYxdsKlIytgJW7zgNuetw53fG3SssfZiiMfbuYnOtvvvYBXTwpbz07V6Czp029Q== +0 -0
  36. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cpg4cb7H0TaehHy4a-xINJMFfBM2_AEHal_0tIX8ymNVJPsjlCysi3-Cad0Ca_SvuGwVM7ONF55OBUuC9YKZvA== +0 -0
  37. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~cuHjdTCuciVumvEpvozxwDj2wAdgWe13bzd1pUAGN45-WOgY0kIid9aUlBX675OnS-xNEc_pyQWo0RO1dKAjcw== +0 -0
  38. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~f_-bfn-KRHHFg39_MtwgBulEAuWH6F05yqGYydXhil6kqZ51eAoRX6tsiqOr0Oa6eL3dK1tcCBD1bWX5orCZhw== +0 -0
  39. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~jdIx7vWS6ej1cqYcbCS4KyZErSMF13ELR95YwClVc98tIXcsglh7KuGvI1gIxEPDtPXQpfC3XijIAGn1quL8Dw== +0 -0
  40. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~lz3e0YeBa8TvMBSSymToh--gc6zznUIdH2jO0AJ4so5OPNdw6wpYmJebhaENGsRoD3beUXvlyD5f7_WeZrzyNQ== +0 -0
  41. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~u_5dWbliYJ__YkyUCDFjdxiFds9M8Epr_RvbU1rIRCbBQdhRJ_TUBXXcL_Qq-wVp4umNLTOzud4OpQItSpO6Rg== +0 -0
  42. package/Tests/Artifacts/LottieTests.xcresult/Data/refs.0~v-YGzhC2l_icsAsyp1XAbEWYwxNook-rARAWlVZINioEsgT9LGvhg2oh78nYqoeH78m1fihr5HCcGNfF7SQj0g== +0 -0
  43. package/Tests/Artifacts/LottieTests.xcresult/Info.plist +29 -0
  44. package/lottie-ios.podspec +1 -1
  45. package/package.json +1 -1
@@ -1,12 +1 @@
1
- # These are supported funding model platforms
2
-
3
- github: [buba447]
4
- patreon: # Replace with a single Patreon username
5
1
  open_collective: lottie
6
- ko_fi: # Replace with a single Ko-fi username
7
- tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
- community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
- liberapay: # Replace with a single Liberapay username
10
- issuehunt: # Replace with a single IssueHunt username
11
- otechie: # Replace with a single Otechie username
12
- custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -2674,8 +2674,8 @@
2674
2674
  isa = XCRemoteSwiftPackageReference;
2675
2675
  repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing.git";
2676
2676
  requirement = {
2677
- branch = main;
2678
- kind = branch;
2677
+ kind = revision;
2678
+ revision = 0c2826f26d00ff5ddf2de92cb6b2139b0dd3d1ee;
2679
2679
  };
2680
2680
  };
2681
2681
  6D0E635D28246BD0007C5DB6 /* XCRemoteSwiftPackageReference "Difference" */ = {
@@ -0,0 +1,22 @@
1
+ {
2
+ "pins" : [
3
+ {
4
+ "identity" : "difference",
5
+ "kind" : "remoteSourceControl",
6
+ "location" : "https://github.com/krzysztofzablocki/Difference",
7
+ "state" : {
8
+ "revision" : "02fe1111edc8318c4f8a0da96336fcbcc201f38b",
9
+ "version" : "1.0.1"
10
+ }
11
+ },
12
+ {
13
+ "identity" : "swift-snapshot-testing",
14
+ "kind" : "remoteSourceControl",
15
+ "location" : "https://github.com/pointfreeco/swift-snapshot-testing.git",
16
+ "state" : {
17
+ "revision" : "0c2826f26d00ff5ddf2de92cb6b2139b0dd3d1ee"
18
+ }
19
+ }
20
+ ],
21
+ "version" : 2
22
+ }
@@ -23,8 +23,8 @@
23
23
  "package": "swift-snapshot-testing",
24
24
  "repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
25
25
  "state": {
26
- "branch": "main",
27
- "revision": "88f6e2c0afe04221fcfb1601a2ecaad83115a05f",
26
+ "branch": null,
27
+ "revision": "0c2826f26d00ff5ddf2de92cb6b2139b0dd3d1ee",
28
28
  "version": null
29
29
  }
30
30
  }
@@ -56,22 +56,25 @@ extension CombinedShapeItem {
56
56
  /// Manually combines the given shape keyframes by manually interpolating at each frame
57
57
  static func manuallyInterpolating(
58
58
  shapes: [KeyframeGroup<BezierPath>],
59
- name: String,
60
- context: LayerContext)
59
+ name: String)
61
60
  -> CombinedShapeItem
62
61
  {
63
- let animationTimeRange = Int(context.animation.startFrame)...Int(context.animation.endFrame)
64
-
65
62
  let interpolators = shapes.map { shape in
66
63
  KeyframeInterpolator(keyframes: shape.keyframes)
67
64
  }
68
65
 
69
- let interpolatedKeyframes = animationTimeRange.map { frame in
66
+ let times = shapes.flatMap { $0.keyframes.map { $0.time } }
67
+
68
+ let minimumTime = times.min() ?? 0
69
+ let maximumTime = times.max() ?? 0
70
+ let animationLocalTimeRange = Int(minimumTime)...Int(maximumTime)
71
+
72
+ let interpolatedKeyframes = animationLocalTimeRange.map { localTime in
70
73
  Keyframe(
71
74
  value: interpolators.compactMap { interpolator in
72
- interpolator.value(frame: AnimationFrameTime(frame)) as? BezierPath
75
+ interpolator.value(frame: AnimationFrameTime(localTime)) as? BezierPath
73
76
  },
74
- time: AnimationFrameTime(frame))
77
+ time: AnimationFrameTime(localTime))
75
78
  }
76
79
 
77
80
  return CombinedShapeItem(
@@ -157,7 +157,7 @@ final class GroupLayer: BaseAnimationLayer {
157
157
  // interpolate the path for each shape at each frame ahead of time so we can combine them
158
158
  // into a single set of bezier path keyframes.
159
159
  else {
160
- combinedShape = .manuallyInterpolating(shapes: allPathKeyframes, name: group.name, context: context)
160
+ combinedShape = .manuallyInterpolating(shapes: allPathKeyframes, name: group.name)
161
161
  }
162
162
 
163
163
  let sublayer = try ShapeItemLayer(
@@ -80,7 +80,7 @@ extension Array where Element == ShapeItem {
80
80
  nodeTree.paths.append(contentsOf: tree.paths)
81
81
  nodeTree.renderContainers.append(node.container)
82
82
  } else if item is Repeater {
83
- LottieLogger.shared.assertionFailure("""
83
+ LottieLogger.shared.warn("""
84
84
  The Main Thread rendering engine doesn't currently support repeaters.
85
85
  To play an animation with repeaters, you can use the Core Animation rendering engine instead.
86
86
  """)
@@ -15,6 +15,7 @@ final class Marker: Codable, DictionaryInitializable {
15
15
  init(dictionary: [String: Any]) throws {
16
16
  name = try dictionary.value(for: CodingKeys.name)
17
17
  frameTime = try dictionary.value(for: CodingKeys.frameTime)
18
+ durationFrameTime = try dictionary.value(for: CodingKeys.durationFrameTime)
18
19
  }
19
20
 
20
21
  // MARK: Internal
@@ -22,6 +23,7 @@ final class Marker: Codable, DictionaryInitializable {
22
23
  enum CodingKeys: String, CodingKey {
23
24
  case name = "cm"
24
25
  case frameTime = "tm"
26
+ case durationFrameTime = "dr"
25
27
  }
26
28
 
27
29
  /// The Marker Name
@@ -30,4 +32,6 @@ final class Marker: Codable, DictionaryInitializable {
30
32
  /// The Frame time of the marker
31
33
  let frameTime: AnimationFrameTime
32
34
 
35
+ /// The duration of the marker, in frames.
36
+ let durationFrameTime: AnimationFrameTime
33
37
  }
@@ -234,6 +234,21 @@ extension Animation {
234
234
  return marker.frameTime
235
235
  }
236
236
 
237
+ /// Markers are a way to describe a point in time and a duration by a key name.
238
+ ///
239
+ /// Markers are encoded into animation JSON. By using markers a designer can mark
240
+ /// playback points for a developer to use without having to worry about keeping
241
+ /// track of animation frames. If the animation file is updated, the developer
242
+ /// does not need to update playback code.
243
+ ///
244
+ /// - Returns: The duration frame time for the marker, or `nil` if no marker found.
245
+ public func durationFrameTime(forMarker named: String) -> AnimationFrameTime? {
246
+ guard let marker = markerMap?[named] else {
247
+ return nil
248
+ }
249
+ return marker.durationFrameTime
250
+ }
251
+
237
252
  /// Converts Frame Time (Seconds * Framerate) into Progress Time
238
253
  /// (optionally clamped to between 0 and 1).
239
254
  public func progressTime(
@@ -513,6 +513,32 @@ final public class AnimationView: AnimationViewBase {
513
513
  addNewAnimationForContext(context)
514
514
  }
515
515
 
516
+ /// Plays the animation from a named marker to the end of the marker's duration.
517
+ ///
518
+ /// A marker is a point in time with an associated duration that is encoded into the
519
+ /// animation data and assigned a name.
520
+ ///
521
+ /// NOTE: If marker is not found the play command will exit.
522
+ ///
523
+ /// - Parameter marker: The start marker for the animation playback.
524
+ /// - Parameter loopMode: The loop behavior of the animation. If `nil` the view's `loopMode` property will be used.
525
+ /// - Parameter completion: An optional completion closure to be called when the animation stops.
526
+ public func play(
527
+ marker: String,
528
+ loopMode: LottieLoopMode? = nil,
529
+ completion: LottieCompletionBlock? = nil)
530
+ {
531
+ guard let from = animation?.markerMap?[marker] else {
532
+ return
533
+ }
534
+
535
+ play(
536
+ fromFrame: from.frameTime,
537
+ toFrame: from.frameTime + from.durationFrameTime,
538
+ loopMode: loopMode,
539
+ completion: completion)
540
+ }
541
+
516
542
  /// Stops the animation and resets the view to its start frame.
517
543
  ///
518
544
  /// The completion closure will be called with `false`
@@ -713,6 +739,21 @@ final public class AnimationView: AnimationViewBase {
713
739
  return animation.frameTime(forMarker: named)
714
740
  }
715
741
 
742
+ /// Markers are a way to describe a point in time and a duration by a key name.
743
+ ///
744
+ /// Markers are encoded into animation JSON. By using markers a designer can mark
745
+ /// playback points for a developer to use without having to worry about keeping
746
+ /// track of animation frames. If the animation file is updated, the developer
747
+ /// does not need to update playback code.
748
+ ///
749
+ /// - Returns: The duration frame time for the marker, or `nil` if no marker found.
750
+ public func durationFrameTime(forMarker named: String) -> AnimationFrameTime? {
751
+ guard let animation = animation else {
752
+ return nil
753
+ }
754
+ return animation.durationFrameTime(forMarker: named)
755
+ }
756
+
716
757
  // MARK: Internal
717
758
 
718
759
  var animationLayer: RootAnimationLayer? = nil
@@ -31,29 +31,9 @@ open class AnimatedButton: AnimatedControl {
31
31
  isAccessibilityElement = true
32
32
  }
33
33
 
34
- // MARK: Public
35
-
36
- public override var accessibilityTraits: UIAccessibilityTraits {
37
- set { super.accessibilityTraits = newValue }
38
- get { super.accessibilityTraits.union(.button) }
39
- }
40
-
41
- /// Sets the play range for the given UIControlEvent.
42
- public func setPlayRange(fromProgress: AnimationProgressTime, toProgress: AnimationProgressTime, event: UIControl.Event) {
43
- rangesForEvents[event.rawValue] = (from: fromProgress, to: toProgress)
44
- }
34
+ // MARK: Open
45
35
 
46
- /// Sets the play range for the given UIControlEvent.
47
- public func setPlayRange(fromMarker fromName: String, toMarker toName: String, event: UIControl.Event) {
48
- if
49
- let start = animationView.progressTime(forMarker: fromName),
50
- let end = animationView.progressTime(forMarker: toName)
51
- {
52
- rangesForEvents[event.rawValue] = (from: start, to: end)
53
- }
54
- }
55
-
56
- public override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
36
+ open override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
57
37
  let _ = super.beginTracking(touch, with: event)
58
38
  let touchEvent = UIControl.Event.touchDown
59
39
  if let playrange = rangesForEvents[touchEvent.rawValue] {
@@ -62,7 +42,7 @@ open class AnimatedButton: AnimatedControl {
62
42
  return true
63
43
  }
64
44
 
65
- public override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
45
+ open override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
66
46
  super.endTracking(touch, with: event)
67
47
  let touchEvent: UIControl.Event
68
48
  if let touch = touch, bounds.contains(touch.location(in: self)) {
@@ -76,6 +56,28 @@ open class AnimatedButton: AnimatedControl {
76
56
  }
77
57
  }
78
58
 
59
+ // MARK: Public
60
+
61
+ public override var accessibilityTraits: UIAccessibilityTraits {
62
+ set { super.accessibilityTraits = newValue }
63
+ get { super.accessibilityTraits.union(.button) }
64
+ }
65
+
66
+ /// Sets the play range for the given UIControlEvent.
67
+ public func setPlayRange(fromProgress: AnimationProgressTime, toProgress: AnimationProgressTime, event: UIControl.Event) {
68
+ rangesForEvents[event.rawValue] = (from: fromProgress, to: toProgress)
69
+ }
70
+
71
+ /// Sets the play range for the given UIControlEvent.
72
+ public func setPlayRange(fromMarker fromName: String, toMarker toName: String, event: UIControl.Event) {
73
+ if
74
+ let start = animationView.progressTime(forMarker: fromName),
75
+ let end = animationView.progressTime(forMarker: toName)
76
+ {
77
+ rangesForEvents[event.rawValue] = (from: start, to: end)
78
+ }
79
+ }
80
+
79
81
  // MARK: Private
80
82
 
81
83
  private var rangesForEvents: [UInt : (from: CGFloat, to: CGFloat)] =
@@ -67,6 +67,18 @@ open class AnimatedSwitch: AnimatedControl {
67
67
  isAccessibilityElement = true
68
68
  }
69
69
 
70
+ // MARK: Open
71
+
72
+ open override func animationDidSet() {
73
+ updateOnState(isOn: _isOn, animated: animateUpdateWhenChangingAnimation, shouldFireHaptics: false)
74
+ }
75
+
76
+ open override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
77
+ super.endTracking(touch, with: event)
78
+ updateOnState(isOn: !_isOn, animated: true, shouldFireHaptics: true)
79
+ sendActions(for: .valueChanged)
80
+ }
81
+
70
82
  // MARK: Public
71
83
 
72
84
  /// Defines what happens when the user taps the switch while an
@@ -79,6 +91,9 @@ open class AnimatedSwitch: AnimatedControl {
79
91
  /// The cancel behavior for the switch. See CancelBehavior for options
80
92
  public var cancelBehavior: CancelBehavior = .reverse
81
93
 
94
+ /// If `false` the switch will not play the animation when changing between animations.
95
+ public var animateUpdateWhenChangingAnimation = true
96
+
82
97
  public override var accessibilityTraits: UIAccessibilityTraits {
83
98
  set { super.accessibilityTraits = newValue }
84
99
  get { super.accessibilityTraits.union(.button) }
@@ -119,16 +134,6 @@ open class AnimatedSwitch: AnimatedControl {
119
134
  updateOnState(isOn: _isOn, animated: false, shouldFireHaptics: false)
120
135
  }
121
136
 
122
- public override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
123
- super.endTracking(touch, with: event)
124
- updateOnState(isOn: !_isOn, animated: true, shouldFireHaptics: true)
125
- sendActions(for: .valueChanged)
126
- }
127
-
128
- public override func animationDidSet() {
129
- updateOnState(isOn: _isOn, animated: true, shouldFireHaptics: false)
130
- }
131
-
132
137
  // MARK: Internal
133
138
 
134
139
  // MARK: Animation State
@@ -186,6 +186,16 @@ public final class CompatibleAnimationView: UIView {
186
186
  completion: completion)
187
187
  }
188
188
 
189
+ @objc
190
+ public func play(
191
+ marker: String,
192
+ completion: ((Bool) -> Void)? = nil)
193
+ {
194
+ animationView.play(
195
+ marker: marker,
196
+ completion: completion)
197
+ }
198
+
189
199
  @objc
190
200
  public func stop() {
191
201
  animationView.stop()
@@ -302,6 +312,11 @@ public final class CompatibleAnimationView: UIView {
302
312
  animationView.frameTime(forMarker: named) ?? 0
303
313
  }
304
314
 
315
+ @objc
316
+ public func durationFrameTime(forMarker named: String) -> CGFloat {
317
+ animationView.durationFrameTime(forMarker: named) ?? 0
318
+ }
319
+
305
320
  // MARK: Private
306
321
 
307
322
  private let animationView: AnimationView
@@ -0,0 +1 @@
1
+ [{"name":"LottieTests-A17CE926-26F9-42D1-A19F-AD020F4D4595","type":2},{"name":"scheduling.log","type":1}]
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>dateCreated</key>
6
+ <date>2022-10-07T20:55:10Z</date>
7
+ <key>externalLocations</key>
8
+ <array/>
9
+ <key>rootId</key>
10
+ <dict>
11
+ <key>hash</key>
12
+ <string>0~U4plJajEDM_uSZdglhDyj6gQO63mbeKxYP9X94aIaOtL0yErtfQnGz5SgsqQ0ToSZcJj6Ao9Wx-nesZVwBTRuw==</string>
13
+ </dict>
14
+ <key>storage</key>
15
+ <dict>
16
+ <key>backend</key>
17
+ <string>fileBacked2</string>
18
+ <key>compression</key>
19
+ <string>standard</string>
20
+ </dict>
21
+ <key>version</key>
22
+ <dict>
23
+ <key>major</key>
24
+ <integer>3</integer>
25
+ <key>minor</key>
26
+ <integer>39</integer>
27
+ </dict>
28
+ </dict>
29
+ </plist>
@@ -8,7 +8,7 @@
8
8
 
9
9
  Pod::Spec.new do |s|
10
10
  s.name = 'lottie-ios'
11
- s.version = '3.4.3'
11
+ s.version = '3.4.4'
12
12
  s.summary = 'A library to render native animations from bodymovin json'
13
13
 
14
14
  s.description = <<-DESC
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lottie-ios",
3
- "version": "3.4.3",
3
+ "version": "3.4.4",
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": {