lottie-ios 4.5.0 → 4.5.1

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 (104) hide show
  1. package/.github/workflows/main.yml +15 -15
  2. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  3. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +7 -20
  4. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +15 -0
  5. package/Package.resolved +2 -2
  6. package/Package.swift +6 -1
  7. package/README.md +2 -2
  8. package/Sources/Private/CoreAnimation/Animations/CombinedShapeAnimation.swift +7 -0
  9. package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +2 -2
  10. package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +2 -0
  11. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +14 -4
  12. package/Sources/Private/CoreAnimation/Layers/GradientRenderLayer.swift +1 -1
  13. package/Sources/Private/CoreAnimation/ValueProviderStore.swift +5 -0
  14. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Collection+Diff.swift +1 -1
  15. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/IndexChangeset.swift +1 -1
  16. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Logging/EpoxyLogger.swift +2 -2
  17. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +1 -1
  18. package/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift +3 -3
  19. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift +6 -3
  20. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive.swift +15 -15
  21. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Serialization.swift +1 -2
  22. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Entry.swift +1 -1
  23. package/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift +2 -3
  24. package/Sources/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.swift +15 -15
  25. package/Sources/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.swift +1 -1
  26. package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +4 -4
  27. package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +1 -1
  28. package/Sources/Private/MainThread/LayerContainers/CompLayers/SolidCompositionLayer.swift +1 -1
  29. package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +11 -0
  30. package/Sources/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.swift +1 -1
  31. package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +0 -37
  32. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +6 -6
  33. package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.swift +5 -0
  34. package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/AnyNodeProperty.swift +3 -0
  35. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/RoundedCornersNode.swift +1 -1
  36. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +3 -3
  37. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +1 -1
  38. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +15 -15
  39. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +3 -3
  40. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +2 -2
  41. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/EllipseNode.swift +2 -2
  42. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/PolygonNode.swift +5 -5
  43. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/RectNode.swift +4 -4
  44. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/ShapeNode.swift +1 -1
  45. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/PathNodes/StarNode.swift +8 -8
  46. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +10 -10
  47. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/FillNode.swift +2 -2
  48. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +4 -4
  49. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +7 -7
  50. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +5 -5
  51. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +1 -1
  52. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +6 -6
  53. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +17 -17
  54. package/Sources/Private/Model/Assets/Asset.swift +1 -1
  55. package/Sources/Private/Model/Assets/AssetLibrary.swift +6 -6
  56. package/Sources/Private/Model/Assets/ImageAsset.swift +7 -0
  57. package/Sources/Private/Model/Assets/PrecompAsset.swift +9 -0
  58. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +1 -1
  59. package/Sources/Private/Model/LayerEffects/DropShadowEffect.swift +9 -0
  60. package/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift +9 -0
  61. package/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift +1 -1
  62. package/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift +9 -0
  63. package/Sources/Private/Model/LayerEffects/LayerEffect.swift +1 -1
  64. package/Sources/Private/Model/LayerStyles/DropShadowStyle.swift +9 -0
  65. package/Sources/Private/Model/LayerStyles/LayerStyle.swift +1 -1
  66. package/Sources/Private/Model/Layers/ImageLayerModel.swift +9 -0
  67. package/Sources/Private/Model/Layers/LayerModel.swift +1 -1
  68. package/Sources/Private/Model/Layers/PreCompLayerModel.swift +9 -0
  69. package/Sources/Private/Model/Layers/ShapeLayerModel.swift +9 -0
  70. package/Sources/Private/Model/Layers/SolidLayerModel.swift +9 -0
  71. package/Sources/Private/Model/Layers/TextLayerModel.swift +9 -0
  72. package/Sources/Private/Model/ShapeItems/Ellipse.swift +7 -0
  73. package/Sources/Private/Model/ShapeItems/Fill.swift +7 -0
  74. package/Sources/Private/Model/ShapeItems/GradientFill.swift +7 -0
  75. package/Sources/Private/Model/ShapeItems/GradientStroke.swift +7 -0
  76. package/Sources/Private/Model/ShapeItems/Group.swift +9 -0
  77. package/Sources/Private/Model/ShapeItems/Merge.swift +7 -0
  78. package/Sources/Private/Model/ShapeItems/Rectangle.swift +9 -0
  79. package/Sources/Private/Model/ShapeItems/Repeater.swift +9 -0
  80. package/Sources/Private/Model/ShapeItems/RoundedCorners.swift +7 -0
  81. package/Sources/Private/Model/ShapeItems/Shape.swift +9 -0
  82. package/Sources/Private/Model/ShapeItems/ShapeItem.swift +1 -1
  83. package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +9 -0
  84. package/Sources/Private/Model/ShapeItems/Star.swift +7 -0
  85. package/Sources/Private/Model/ShapeItems/Stroke.swift +9 -0
  86. package/Sources/Private/Model/ShapeItems/Trim.swift +9 -2
  87. package/Sources/Private/RootAnimationLayer.swift +1 -0
  88. package/Sources/Private/Utility/Extensions/MathKit.swift +3 -4
  89. package/Sources/Private/Utility/Helpers/AnimationContext.swift +2 -2
  90. package/Sources/Public/Animation/LottieAnimationLayer.swift +13 -3
  91. package/Sources/Public/Animation/LottieAnimationView.swift +11 -2
  92. package/Sources/Public/Animation/LottieView.swift +6 -5
  93. package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +1 -1
  94. package/Sources/Public/Controls/AnimatedControl.swift +5 -0
  95. package/Sources/Public/Controls/AnimatedSwitch.swift +4 -4
  96. package/Sources/Public/Controls/LottieButton.swift +1 -1
  97. package/Sources/Public/Controls/LottieSwitch.swift +1 -1
  98. package/Sources/Public/DotLottie/Cache/DotLottieCache.swift +1 -1
  99. package/Sources/Public/Keyframes/Keyframe.swift +1 -1
  100. package/Sources/Public/Logging/LottieLogger.swift +2 -2
  101. package/Sources/Public/macOS/LottieAnimationViewBase.macOS.swift +1 -1
  102. package/Version.xcconfig +2 -2
  103. package/lottie-ios.podspec +1 -1
  104. package/package.json +1 -1
@@ -16,7 +16,7 @@ jobs:
16
16
  xcode:
17
17
  - '15.0.1' # Swift 5.9, but no visionOS support
18
18
  steps:
19
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v4
20
20
  - uses: ./.github/actions/setup
21
21
  with:
22
22
  xcode: ${{ matrix.xcode }}
@@ -34,7 +34,7 @@ jobs:
34
34
  - '15.2' # Swift 5.9
35
35
  - '15.3' # Swift 5.10
36
36
  steps:
37
- - uses: actions/checkout@v2
37
+ - uses: actions/checkout@v4
38
38
  - uses: ./.github/actions/setup
39
39
  with:
40
40
  xcode: ${{ matrix.xcode }}
@@ -46,7 +46,7 @@ jobs:
46
46
  name: "Build Example App"
47
47
  runs-on: macos-14
48
48
  steps:
49
- - uses: actions/checkout@v2
49
+ - uses: actions/checkout@v4
50
50
  - uses: ./.github/actions/setup
51
51
  with:
52
52
  xcode: '15.3' # Swift 5.10
@@ -57,7 +57,7 @@ jobs:
57
57
  name: "Test Package"
58
58
  runs-on: macos-14
59
59
  steps:
60
- - uses: actions/checkout@v2
60
+ - uses: actions/checkout@v4
61
61
  - uses: ./.github/actions/setup
62
62
  with:
63
63
  xcode: '15.3' # Swift 5.10
@@ -68,7 +68,7 @@ jobs:
68
68
  run: bundle exec rake test:process
69
69
  - name: Upload artifacts
70
70
  if: always()
71
- uses: actions/upload-artifact@v2
71
+ uses: actions/upload-artifact@v4
72
72
  with:
73
73
  name: TestArtifacts
74
74
  path: Tests/Artifacts
@@ -77,7 +77,7 @@ jobs:
77
77
  name: "Emerge Upload"
78
78
  runs-on: macos-14
79
79
  steps:
80
- - uses: actions/checkout@v2
80
+ - uses: actions/checkout@v4
81
81
  - uses: ./.github/actions/setup
82
82
  - name: Build Package
83
83
  run: bundle exec rake emerge:upload
@@ -100,8 +100,8 @@ jobs:
100
100
  # Xcode 15.0 can use an XCFramework built by Xcode 15.2.
101
101
  - '15.2' # Swift 5.9, first Xcode version with visionOS support.
102
102
  steps:
103
- - uses: actions/checkout@v2
104
- - uses: apple-actions/import-codesign-certs@v2
103
+ - uses: actions/checkout@v4
104
+ - uses: apple-actions/import-codesign-certs@v3
105
105
  continue-on-error: true
106
106
  with:
107
107
  p12-file-base64: ${{ secrets.SIGNING_CERTIFICATE_BASE_64 }}
@@ -110,9 +110,9 @@ jobs:
110
110
  with:
111
111
  xcode: ${{ matrix.xcode }}
112
112
  - name: Build XCFramework
113
- run: bundle exec rake build:xcframework[Lottie-Xcode-${{ matrix.xcode }}]
113
+ run: bundle exec rake build:xcframework
114
114
  - name: Upload XCFramework
115
- uses: actions/upload-artifact@v2
115
+ uses: actions/upload-artifact@v4
116
116
  with:
117
117
  name: BuildProducts
118
118
  path: .build/archives
@@ -125,7 +125,7 @@ jobs:
125
125
  xcode:
126
126
  - '15.3' # Swift 5.10
127
127
  steps:
128
- - uses: actions/checkout@v2
128
+ - uses: actions/checkout@v4
129
129
  - uses: ./.github/actions/setup
130
130
  with:
131
131
  install-mint: false
@@ -141,7 +141,7 @@ jobs:
141
141
  xcode:
142
142
  - '15.3' # Swift 5.10
143
143
  steps:
144
- - uses: actions/checkout@v2
144
+ - uses: actions/checkout@v4
145
145
  - uses: ./.github/actions/setup
146
146
  with:
147
147
  install-mint: true
@@ -153,7 +153,7 @@ jobs:
153
153
  name: "Test Carthage support"
154
154
  runs-on: macos-14
155
155
  steps:
156
- - uses: actions/checkout@v2
156
+ - uses: actions/checkout@v4
157
157
  - uses: ./.github/actions/setup
158
158
  with:
159
159
  install-mint: true
@@ -166,7 +166,7 @@ jobs:
166
166
  name: "Lint Swift"
167
167
  runs-on: macos-14
168
168
  steps:
169
- - uses: actions/checkout@v2
169
+ - uses: actions/checkout@v4
170
170
  - uses: ./.github/actions/setup
171
171
  - name: Lint Swift
172
172
  run: bundle exec rake lint:swift
@@ -175,7 +175,7 @@ jobs:
175
175
  name: "Lint Embedded Libraries"
176
176
  runs-on: macos-14
177
177
  steps:
178
- - uses: actions/checkout@v2
178
+ - uses: actions/checkout@v4
179
179
  - uses: ./.github/actions/setup
180
180
  - name: Lint Embedded Libraries
181
181
  run: bundle exec rake lint:EmbeddedLibraries
@@ -7,30 +7,17 @@
7
7
  <BreakpointProxy
8
8
  BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
9
9
  <BreakpointContent
10
- uuid = "9F6F6DCE-17A1-4400-B8C2-87FC3C2073DF"
11
- shouldBeEnabled = "No"
12
- condition = "customShape.direction != nil"
10
+ uuid = "608732A3-8389-4BD4-A600-81DB4BAB3BEB"
11
+ shouldBeEnabled = "Yes"
13
12
  ignoreCount = "0"
14
13
  continueAfterRunningActions = "No"
15
- filePath = "Sources/Private/CoreAnimation/Animations/ShapeAnimation.swift"
14
+ filePath = "Sources/Public/Animation/LottieAnimationLayer.swift"
16
15
  startingColumnNumber = "9223372036854775807"
17
16
  endingColumnNumber = "9223372036854775807"
18
- startingLineNumber = "18"
19
- endingLineNumber = "18"
20
- landmarkName = "CAShapeLayer"
21
- landmarkType = "21">
22
- </BreakpointContent>
23
- </BreakpointProxy>
24
- <BreakpointProxy
25
- BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
26
- <BreakpointContent
27
- uuid = "CC6852A0-E9B0-4870-9299-A62D4DE8C83A"
28
- shouldBeEnabled = "Yes"
29
- ignoreCount = "0"
30
- continueAfterRunningActions = "No"
31
- breakpointStackSelectionBehavior = "1"
32
- scope = "1"
33
- stopOnStyle = "0">
17
+ startingLineNumber = "689"
18
+ endingLineNumber = "689"
19
+ landmarkName = "currentTime"
20
+ landmarkType = "24">
34
21
  </BreakpointContent>
35
22
  </BreakpointProxy>
36
23
  </Breakpoints>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <VariablesViewState
3
+ version = "1.0">
4
+ <ContextStates>
5
+ <ContextState
6
+ contextName = "CoreAnimationLayer.init(animation:imageProvider:textProvider:fontProvider:maskAnimationToBounds:compatibilityTrackerMode:logger:):CoreAnimationLayer.swift">
7
+ </ContextState>
8
+ <ContextState
9
+ contextName = "CAShapeLayer.addAnimations(for:context:pathMultiplier:transformPath:roundedCorners:):CustomPathAnimation.swift">
10
+ </ContextState>
11
+ <ContextState
12
+ contextName = "closure #1 in CAShapeLayer.addAnimations(for:context:pathMultiplier:transformPath:roundedCorners:):CustomPathAnimation.swift">
13
+ </ContextState>
14
+ </ContextStates>
15
+ </VariablesViewState>
package/Package.resolved CHANGED
@@ -5,8 +5,8 @@
5
5
  "kind" : "remoteSourceControl",
6
6
  "location" : "https://github.com/airbnb/swift",
7
7
  "state" : {
8
- "revision" : "fa3ae574d0b9c93a1655424bd4381044274c5cb4",
9
- "version" : "1.0.7"
8
+ "revision" : "c7e833face3f893b8defde66eecb66f24b55ca35",
9
+ "version" : "1.0.8"
10
10
  }
11
11
  },
12
12
  {
package/Package.swift CHANGED
@@ -5,7 +5,12 @@ let package = Package(
5
5
  name: "Lottie",
6
6
  // Minimum platform versions should be kept in sync with the per-platform targets in Lottie.xcodeproj, lottie-ios.podspec, and lottie-spm's Package.swift
7
7
  platforms: [.iOS("13.0"), .macOS("10.15"), .tvOS("13.0"), .custom("visionOS", versionString: "1.0")],
8
- products: [.library(name: "Lottie", targets: ["Lottie"])],
8
+ products: [
9
+ .library(name: "Lottie", targets: ["Lottie"]),
10
+ // Product for dynamic linking, as SPM builds libraries statically by default.
11
+ // This product should be used in a modular project structure with multiple packages using Lottie to avoid duplicate symbols.
12
+ .library(name: "Lottie-Dynamic", type: .dynamic, targets: ["Lottie"]),
13
+ ],
9
14
  dependencies: [
10
15
  .package(url: "https://github.com/airbnb/swift", .upToNextMajor(from: "1.0.1")),
11
16
  ],
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Lottie is a cross-platform library for iOS, macOS, tvOS, visionOS, [Android](https://github.com/airbnb/lottie-android), and [Web](https://github.com/airbnb/lottie-web) that natively renders vector-based animations and art in realtime with minimal code.
7
7
 
8
- Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haiku.ai).
8
+ Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with [bodymovin](https://github.com/bodymovin/bodymovin), Sketch with [Lottie Sketch Export](https://github.com/buba447/Lottie-Sketch-Export), and from [Haiku](https://www.haikuanimator.com).
9
9
 
10
10
  Designers can create **and ship** beautiful animations without an engineer painstakingly recreating them by hand.
11
11
  Since the animations are backed by JSON, they are extremely small in size but can be large in complexity!
@@ -33,7 +33,7 @@ You can pull the [Lottie Github Repo](https://github.com/airbnb/lottie-ios/) and
33
33
 
34
34
  ### Swift Package Manager
35
35
 
36
- To install Lottie using [Swift Package Manager](https://github.com/apple/swift-package-manager) you can follow the [tutorial published by Apple](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) using the URL for the Lottie repo with the current version:
36
+ To install Lottie using [Swift Package Manager](https://github.com/swiftlang/swift-package-manager) you can follow the [tutorial published by Apple](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) using the URL for the Lottie repo with the current version:
37
37
 
38
38
  1. In Xcode, select “File” → “Add Packages...”
39
39
  1. Enter https://github.com/airbnb/lottie-spm.git
@@ -82,3 +82,10 @@ extension CombinedShapeItem {
82
82
  name: name)
83
83
  }
84
84
  }
85
+
86
+ // MARK: Sendable
87
+
88
+ /// `CombinedShapeItem` inherits `@unchecked Sendable` from `ShapeItem` and
89
+ /// we need to restate that here to avoid a warning in Xcode 16
90
+ // swiftlint:disable:next no_unchecked_sendable
91
+ extension CombinedShapeItem: @unchecked Sendable { }
@@ -61,8 +61,8 @@ struct BezierPathKeyframe: Interpolatable {
61
61
  /// that can have different counts / timing parameters
62
62
  static func combining(
63
63
  path: KeyframeGroup<BezierPath>,
64
- cornerRadius: KeyframeGroup<LottieVector1D>?) throws
65
- -> KeyframeGroup<BezierPathKeyframe>
64
+ cornerRadius: KeyframeGroup<LottieVector1D>?)
65
+ throws -> KeyframeGroup<BezierPathKeyframe>
66
66
  {
67
67
  guard
68
68
  let cornerRadius,
@@ -23,6 +23,7 @@ extension Stroke: StrokeShapeItem {
23
23
 
24
24
  func copy(width: KeyframeGroup<LottieVector1D>) -> StrokeShapeItem {
25
25
  // Type-erase the copy from `Stroke` to `StrokeShapeItem`
26
+ // swiftformat:disable:next redundantProperty
26
27
  let copy: Stroke = copy(width: width)
27
28
  return copy
28
29
  }
@@ -35,6 +36,7 @@ extension GradientStroke: StrokeShapeItem {
35
36
 
36
37
  func copy(width: KeyframeGroup<LottieVector1D>) -> StrokeShapeItem {
37
38
  // Type-erase the copy from `GradientStroke` to `StrokeShapeItem`
39
+ // swiftformat:disable:next redundantProperty
38
40
  let copy: GradientStroke = copy(width: width)
39
41
  return copy
40
42
  }
@@ -424,9 +424,11 @@ extension CoreAnimationLayer: RootAnimationLayer {
424
424
  var respectAnimationFrameRate: Bool {
425
425
  get { false }
426
426
  set {
427
- logger.assertionFailure("""
428
- The Core Animation rendering engine currently doesn't support `respectAnimationFrameRate`)
429
- """)
427
+ if newValue {
428
+ logger.assertionFailure("""
429
+ The Core Animation rendering engine currently doesn't support `respectAnimationFrameRate`)
430
+ """)
431
+ }
430
432
  }
431
433
  }
432
434
 
@@ -495,6 +497,14 @@ extension CoreAnimationLayer: RootAnimationLayer {
495
497
  rebuildCurrentAnimation()
496
498
  }
497
499
 
500
+ func removeValueProvider(for keypath: AnimationKeypath) {
501
+ valueProviderStore.removeValueProvider(for: keypath)
502
+
503
+ // We need to rebuild the current animation after removing a value provider,
504
+ // since any existing `CAAnimation`s could now be out of date.
505
+ rebuildCurrentAnimation()
506
+ }
507
+
498
508
  func getValue(for _: AnimationKeypath, atFrame _: AnimationFrameTime?) -> Any? {
499
509
  logger.assertionFailure("""
500
510
  The Core Animation rendering engine doesn't support querying values for individual frames
@@ -584,7 +594,7 @@ extension CALayer {
584
594
  var numberOfSublayersWithTimeRemapping = 0
585
595
 
586
596
  for sublayer in sublayers ?? [] {
587
- if
597
+ if
588
598
  let preCompLayer = sublayer as? PreCompLayer,
589
599
  preCompLayer.preCompLayer.timeRemapping != nil
590
600
  {
@@ -25,7 +25,7 @@ final class GradientRenderLayer: CAGradientLayer {
25
25
 
26
26
  /// The reference bounds within this layer that the gradient's
27
27
  /// `startPoint` and `endPoint` should be calculated relative to
28
- var gradientReferenceBounds: CGRect = .zero {
28
+ var gradientReferenceBounds = CGRect.zero {
29
29
  didSet {
30
30
  if oldValue != gradientReferenceBounds {
31
31
  updateLayout()
@@ -40,6 +40,11 @@ final class ValueProviderStore {
40
40
  valueProviders.append((keypath: keypath, valueProvider: valueProvider))
41
41
  }
42
42
 
43
+ /// Removes all ValueProviders for the given `AnimationKeypath`
44
+ func removeValueProvider(for keypath: AnimationKeypath) {
45
+ valueProviders.removeAll(where: { $0.keypath.matches(keypath) })
46
+ }
47
+
43
48
  /// Retrieves the custom value keyframes for the given property,
44
49
  /// if an `AnyValueProvider` was registered for the given keypath.
45
50
  func customKeyframes<Value>(
@@ -203,7 +203,7 @@ extension Collection where Element: DiffableSection, Index == Int {
203
203
 
204
204
  // MARK: - EpoxyEntry
205
205
 
206
- /// A bookkeeping refrence type for the diffing algorithm.
206
+ /// A bookkeeping reference type for the diffing algorithm.
207
207
  private final class EpoxyEntry {
208
208
 
209
209
  // MARK: Internal
@@ -116,7 +116,7 @@ struct IndexPathChangeset {
116
116
  inserts.isEmpty && deletes.isEmpty && updates.isEmpty && moves.isEmpty
117
117
  }
118
118
 
119
- static func += (left: inout IndexPathChangeset, right: IndexPathChangeset) {
119
+ static func +=(left: inout IndexPathChangeset, right: IndexPathChangeset) {
120
120
  left.inserts += right.inserts
121
121
  left.deletes += right.deletes
122
122
  left.updates += right.updates
@@ -11,14 +11,14 @@ final class EpoxyLogger {
11
11
  assert: @escaping Assert = { condition, message, file, line in
12
12
  // If we default to `Swift.assert` directly with `assert: Assert = Swift.assert`,
13
13
  // the call will unexpectedly not respect the -O flag and will crash in release
14
- // https://github.com/apple/swift/issues/60249
14
+ // https://github.com/swiftlang/swift/issues/60249
15
15
  Swift.assert(condition(), message(), file: file, line: line)
16
16
  },
17
17
  assertionFailure: @escaping AssertionFailure = { message, file, line in
18
18
  // If we default to `Swift.assertionFailure` directly with
19
19
  // `assertionFailure: AssertionFailure = Swift.assertionFailure`,
20
20
  // the call will unexpectedly not respect the -O flag and will crash in release
21
- // https://github.com/apple/swift/issues/60249
21
+ // https://github.com/swiftlang/swift/issues/60249
22
22
  Swift.assertionFailure(message(), file: file, line: line)
23
23
  },
24
24
  warn: @escaping Warn = { message, _, _ in
@@ -36,7 +36,7 @@ struct SwiftUIView<Content: ViewType, Storage>: MeasuringViewRepresentable,
36
36
 
37
37
  var configurations: [Configuration] = []
38
38
 
39
- var sizing: SwiftUIMeasurementContainerStrategy = .automatic
39
+ var sizing = SwiftUIMeasurementContainerStrategy.automatic
40
40
 
41
41
  // MARK: Private
42
42
 
@@ -43,8 +43,8 @@ let LRUCacheMemoryWarningNotification: NSNotification.Name =
43
43
  #else
44
44
 
45
45
  /// Notification that cache should be cleared
46
- let LRUCacheMemoryWarningNotification: NSNotification.Name =
47
- .init("LRUCacheMemoryWarningNotification")
46
+ let LRUCacheMemoryWarningNotification =
47
+ NSNotification.Name("LRUCacheMemoryWarningNotification")
48
48
 
49
49
  #endif
50
50
 
@@ -99,7 +99,7 @@ final class LRUCache<Key: Hashable, Value> {
99
99
  private var values: [Key: Container] = [:]
100
100
  private unowned(unsafe) var head: Container?
101
101
  private unowned(unsafe) var tail: Container?
102
- private let lock: NSLock = .init()
102
+ private let lock = NSLock()
103
103
  private var token: AnyObject?
104
104
  private let notificationCenter: NotificationCenter
105
105
 
@@ -70,7 +70,8 @@ extension Archive {
70
70
  compressionMethod: CompressionMethod,
71
71
  bufferSize: Int,
72
72
  progress: Progress? = nil,
73
- provider: Provider) throws -> (sizeWritten: Int64, crc32: CRC32)
73
+ provider: Provider)
74
+ throws -> (sizeWritten: Int64, crc32: CRC32)
74
75
  {
75
76
  var checksum = CRC32(0)
76
77
  var sizeWritten = Int64(0)
@@ -266,7 +267,8 @@ extension Archive {
266
267
  size: Int64,
267
268
  bufferSize: Int,
268
269
  progress: Progress? = nil,
269
- provider: Provider) throws -> (sizeWritten: Int64, checksum: CRC32)
270
+ provider: Provider)
271
+ throws -> (sizeWritten: Int64, checksum: CRC32)
270
272
  {
271
273
  var position: Int64 = 0
272
274
  var sizeWritten: Int64 = 0
@@ -287,7 +289,8 @@ extension Archive {
287
289
  size: Int64,
288
290
  bufferSize: Int,
289
291
  progress: Progress? = nil,
290
- provider: Provider) throws -> (sizeWritten: Int64, checksum: CRC32)
292
+ provider: Provider)
293
+ throws -> (sizeWritten: Int64, checksum: CRC32)
291
294
  {
292
295
  var sizeWritten: Int64 = 0
293
296
  let consumer: Consumer = { data in sizeWritten += Int64(try Data.write(chunk: data, to: self.archiveFile)) }
@@ -171,21 +171,6 @@ final class Archive: Sequence {
171
171
  var zip64EndOfCentralDirectory: ZIP64EndOfCentralDirectory?
172
172
  var preferredEncoding: String.Encoding?
173
173
 
174
- var totalNumberOfEntriesInCentralDirectory: UInt64 {
175
- zip64EndOfCentralDirectory?.record.totalNumberOfEntriesInCentralDirectory
176
- ?? UInt64(endOfCentralDirectoryRecord.totalNumberOfEntriesInCentralDirectory)
177
- }
178
-
179
- var sizeOfCentralDirectory: UInt64 {
180
- zip64EndOfCentralDirectory?.record.sizeOfCentralDirectory
181
- ?? UInt64(endOfCentralDirectoryRecord.sizeOfCentralDirectory)
182
- }
183
-
184
- var offsetToStartOfCentralDirectory: UInt64 {
185
- zip64EndOfCentralDirectory?.record.offsetToStartOfCentralDirectory
186
- ?? UInt64(endOfCentralDirectoryRecord.offsetToStartOfCentralDirectory)
187
- }
188
-
189
174
  #if swift(>=5.0)
190
175
  var memoryFile: MemoryFile?
191
176
 
@@ -221,6 +206,21 @@ final class Archive: Sequence {
221
206
  }
222
207
  #endif
223
208
 
209
+ var totalNumberOfEntriesInCentralDirectory: UInt64 {
210
+ zip64EndOfCentralDirectory?.record.totalNumberOfEntriesInCentralDirectory
211
+ ?? UInt64(endOfCentralDirectoryRecord.totalNumberOfEntriesInCentralDirectory)
212
+ }
213
+
214
+ var sizeOfCentralDirectory: UInt64 {
215
+ zip64EndOfCentralDirectory?.record.sizeOfCentralDirectory
216
+ ?? UInt64(endOfCentralDirectoryRecord.sizeOfCentralDirectory)
217
+ }
218
+
219
+ var offsetToStartOfCentralDirectory: UInt64 {
220
+ zip64EndOfCentralDirectory?.record.offsetToStartOfCentralDirectory
221
+ ?? UInt64(endOfCentralDirectoryRecord.offsetToStartOfCentralDirectory)
222
+ }
223
+
224
224
  // MARK: - Helpers
225
225
 
226
226
  static func scanForEndOfCentralDirectoryRecord(in file: FILEPointer)
@@ -38,10 +38,9 @@ extension Data {
38
38
  guard let data = try? readChunk(of: T.size, from: file) else {
39
39
  return nil
40
40
  }
41
- let structure = T(data: data, additionalDataProvider: { additionalDataSize -> Data in
41
+ return T(data: data, additionalDataProvider: { additionalDataSize -> Data in
42
42
  try self.readChunk(of: additionalDataSize, from: file)
43
43
  })
44
- return structure
45
44
  }
46
45
 
47
46
  static func consumePart(
@@ -237,7 +237,7 @@ struct Entry: Equatable {
237
237
  return dataOffset
238
238
  }
239
239
 
240
- static func == (lhs: Entry, rhs: Entry) -> Bool {
240
+ static func ==(lhs: Entry, rhs: Entry) -> Bool {
241
241
  lhs.path == rhs.path
242
242
  && lhs.localFileHeader.crc32 == rhs.localFileHeader.crc32
243
243
  && lhs.centralDirectoryStructure.effectiveRelativeOffsetOfLocalHeader
@@ -89,8 +89,7 @@ extension FileManager {
89
89
  #endif
90
90
 
91
91
  let timeStamp = TimeInterval(modTimeSpec.tv_sec) + TimeInterval(modTimeSpec.tv_nsec) / 1000000000.0
92
- let modDate = Date(timeIntervalSince1970: timeStamp)
93
- return modDate
92
+ return Date(timeIntervalSince1970: timeStamp)
94
93
  }
95
94
 
96
95
  class func fileSizeForItem(at url: URL) throws -> Int64 {
@@ -308,7 +307,7 @@ extension Date {
308
307
  // MARK: Internal
309
308
 
310
309
  var fileModificationDateTime: (UInt16, UInt16) {
311
- (self.fileModificationDate, self.fileModificationTime)
310
+ (fileModificationDate, fileModificationTime)
312
311
  }
313
312
 
314
313
  var fileModificationDate: UInt16 {
@@ -31,26 +31,26 @@ class CompositionLayer: CALayer, KeypathSearchable {
31
31
  super.init()
32
32
  anchorPoint = .zero
33
33
  actions = [
34
- "opacity" : NSNull(),
35
- "transform" : NSNull(),
36
- "bounds" : NSNull(),
37
- "anchorPoint" : NSNull(),
38
- "sublayerTransform" : NSNull(),
39
- "shadowOpacity" : NSNull(),
40
- "shadowOffset" : NSNull(),
41
- "shadowColor" : NSNull(),
42
- "shadowRadius" : NSNull(),
34
+ "opacity": NSNull(),
35
+ "transform": NSNull(),
36
+ "bounds": NSNull(),
37
+ "anchorPoint": NSNull(),
38
+ "sublayerTransform": NSNull(),
39
+ "shadowOpacity": NSNull(),
40
+ "shadowOffset": NSNull(),
41
+ "shadowColor": NSNull(),
42
+ "shadowRadius": NSNull(),
43
43
  ]
44
44
 
45
45
  contentsLayer.anchorPoint = .zero
46
46
  contentsLayer.bounds = CGRect(origin: .zero, size: size)
47
47
  contentsLayer.actions = [
48
- "opacity" : NSNull(),
49
- "transform" : NSNull(),
50
- "bounds" : NSNull(),
51
- "anchorPoint" : NSNull(),
52
- "sublayerTransform" : NSNull(),
53
- "hidden" : NSNull(),
48
+ "opacity": NSNull(),
49
+ "transform": NSNull(),
50
+ "bounds": NSNull(),
51
+ "anchorPoint": NSNull(),
52
+ "sublayerTransform": NSNull(),
53
+ "hidden": NSNull(),
54
54
  ]
55
55
  compositingFilter = layer.blendMode.filterName
56
56
  addSublayer(contentsLayer)
@@ -46,7 +46,7 @@ final class ImageCompositionLayer: CompositionLayer {
46
46
  }
47
47
  }
48
48
 
49
- var imageContentsGravity: CALayerContentsGravity = .resize {
49
+ var imageContentsGravity = CALayerContentsGravity.resize {
50
50
  didSet {
51
51
  contentsLayer.contentsGravity = imageContentsGravity
52
52
  }
@@ -108,7 +108,7 @@ private class MaskLayer: CALayer {
108
108
  : .rgb(0, 1, 0)
109
109
  maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
110
110
  actions = [
111
- "opacity" : NSNull(),
111
+ "opacity": NSNull(),
112
112
  ]
113
113
  }
114
114
 
@@ -168,9 +168,9 @@ private class MaskNodeProperties: NodePropertyMap {
168
168
  shape = NodeProperty(provider: KeyframeInterpolator(keyframes: mask.shape.keyframes))
169
169
  expansion = NodeProperty(provider: KeyframeInterpolator(keyframes: mask.expansion.keyframes))
170
170
  propertyMap = [
171
- PropertyName.opacity.rawValue : opacity,
172
- "Shape" : shape,
173
- "Expansion" : expansion,
171
+ PropertyName.opacity.rawValue: opacity,
172
+ "Shape": shape,
173
+ "Expansion": expansion,
174
174
  ]
175
175
  properties = Array(propertyMap.values)
176
176
  }
@@ -107,7 +107,7 @@ final class PreCompositionLayer: CompositionLayer {
107
107
  guard let remappingNode else {
108
108
  return super.keypathProperties
109
109
  }
110
- return ["Time Remap" : remappingNode]
110
+ return ["Time Remap": remappingNode]
111
111
  }
112
112
 
113
113
  override func displayContentsWithFrame(frame: CGFloat, forceUpdates: Bool) {
@@ -45,7 +45,7 @@ final class SolidCompositionLayer: CompositionLayer {
45
45
 
46
46
  override var keypathProperties: [String: AnyNodeProperty] {
47
47
  guard let colorProperty else { return super.keypathProperties }
48
- return [PropertyName.color.rawValue : colorProperty]
48
+ return [PropertyName.color.rawValue: colorProperty]
49
49
  }
50
50
 
51
51
  override func displayContentsWithFrame(frame: CGFloat, forceUpdates _: Bool) {
@@ -241,6 +241,17 @@ final class MainThreadAnimationLayer: CALayer, RootAnimationLayer {
241
241
  }
242
242
  }
243
243
 
244
+ func removeValueProvider(for keypath: AnimationKeypath) {
245
+ for layer in animationLayers {
246
+ if let foundProperties = layer.nodeProperties(for: keypath) {
247
+ for property in foundProperties {
248
+ property.removeProvider()
249
+ }
250
+ layer.displayWithFrame(frame: presentation()?.currentFrame ?? currentFrame, forceUpdates: true)
251
+ }
252
+ }
253
+ }
254
+
244
255
  func getValue(for keypath: AnimationKeypath, atFrame: CGFloat?) -> Any? {
245
256
  for layer in animationLayers {
246
257
  if
@@ -22,7 +22,7 @@ extension [LayerModel] {
22
22
  -> [CompositionLayer]
23
23
  {
24
24
  var compositionLayers = [CompositionLayer]()
25
- var layerMap = [Int : CompositionLayer]()
25
+ var layerMap = [Int: CompositionLayer]()
26
26
 
27
27
  /// Organize the assets into a dictionary of [ID : ImageAsset]
28
28
  var childLayers = [LayerModel]()