lottie-ios 4.3.0 → 4.3.2
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.
- package/.github/workflows/main.yml +9 -44
- package/Lottie.xcodeproj/project.pbxproj +4 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +50 -36
- package/README.md +1 -1
- package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +3 -4
- package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +5 -1
- package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +19 -0
- package/Sources/Public/Animation/LottieAnimationLayer.swift +102 -40
- package/Sources/Public/Animation/LottieAnimationView.swift +22 -9
- package/Sources/Public/Animation/LottiePlaybackMode.swift +143 -53
- package/Sources/Public/Animation/LottieView.swift +31 -11
- package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +4 -2
- package/lottie-ios.podspec +2 -2
- package/package.json +1 -1
|
@@ -32,30 +32,17 @@ jobs:
|
|
|
32
32
|
xcode:
|
|
33
33
|
- '14.2' # Swift 5.7
|
|
34
34
|
- '14.3' # Swift 5.8
|
|
35
|
+
- '15.0' # Swift 5.9
|
|
35
36
|
steps:
|
|
36
37
|
- uses: actions/checkout@v2
|
|
37
38
|
- uses: ./.github/actions/setup
|
|
38
39
|
with:
|
|
39
40
|
xcode: ${{ matrix.xcode }}
|
|
40
41
|
- name: Build Package
|
|
42
|
+
# Once there is a production Xcode version with the visionOS SDK,
|
|
43
|
+
# we will want to use that version without `SKIP_VISION_OS=true`
|
|
41
44
|
run: SKIP_VISION_OS=true bundle exec rake build:package:all
|
|
42
45
|
|
|
43
|
-
build-package-macos-13-xcode-15:
|
|
44
|
-
name: "Build Package"
|
|
45
|
-
runs-on: macos-13
|
|
46
|
-
strategy:
|
|
47
|
-
fail-fast: false
|
|
48
|
-
matrix:
|
|
49
|
-
xcode:
|
|
50
|
-
- '15.0' # Swift 5.9, first version that includes visionOS SDK.
|
|
51
|
-
steps:
|
|
52
|
-
- uses: actions/checkout@v2
|
|
53
|
-
- uses: ./.github/actions/setup
|
|
54
|
-
with:
|
|
55
|
-
xcode: ${{ matrix.xcode }}
|
|
56
|
-
- name: Build Package
|
|
57
|
-
run: bundle exec rake build:package:all
|
|
58
|
-
|
|
59
46
|
build-example:
|
|
60
47
|
name: "Build Example App"
|
|
61
48
|
runs-on: macos-13
|
|
@@ -65,7 +52,9 @@ jobs:
|
|
|
65
52
|
with:
|
|
66
53
|
xcode: '15.0' # Swift 5.9
|
|
67
54
|
- name: Build Example
|
|
68
|
-
|
|
55
|
+
# Once there is a production Xcode version with the visionOS SDK,
|
|
56
|
+
# we will want to remove `SKIP_VISION_OS=true`
|
|
57
|
+
run: SKIP_VISION_OS=true bundle exec rake build:example:all
|
|
69
58
|
|
|
70
59
|
test-package:
|
|
71
60
|
name: "Test Package"
|
|
@@ -115,6 +104,8 @@ jobs:
|
|
|
115
104
|
with:
|
|
116
105
|
xcode: ${{ matrix.xcode }}
|
|
117
106
|
- name: Build XCFramework
|
|
107
|
+
# Once there is a production Xcode version with the visionOS SDK, we will
|
|
108
|
+
# need to also build an XCFramework using that version but without `SKIP_VISION_OS=true`
|
|
118
109
|
run: SKIP_VISION_OS=true bundle exec rake build:xcframework[Lottie-Xcode-${{ matrix.xcode }}]
|
|
119
110
|
- name: Upload XCFramework
|
|
120
111
|
uses: actions/upload-artifact@v2
|
|
@@ -128,32 +119,6 @@ jobs:
|
|
|
128
119
|
# to an `archives` directory containing our `Lottie.xcframework.zip`.
|
|
129
120
|
path: .build/archives
|
|
130
121
|
|
|
131
|
-
build-xcframework-macos-13:
|
|
132
|
-
name: "Build XCFramework"
|
|
133
|
-
runs-on: macos-13
|
|
134
|
-
strategy:
|
|
135
|
-
matrix:
|
|
136
|
-
xcode:
|
|
137
|
-
- '15.0' # Swift 5.9, and the first Xcode version with the visionOS SDK.
|
|
138
|
-
steps:
|
|
139
|
-
- uses: actions/checkout@v2
|
|
140
|
-
- uses: ./.github/actions/setup
|
|
141
|
-
with:
|
|
142
|
-
xcode: ${{ matrix.xcode }}
|
|
143
|
-
- name: Build XCFramework
|
|
144
|
-
run: bundle exec rake build:xcframework[Lottie-Xcode-${{ matrix.xcode }}]
|
|
145
|
-
- name: Upload XCFramework
|
|
146
|
-
uses: actions/upload-artifact@v2
|
|
147
|
-
with:
|
|
148
|
-
name: BuildProducts
|
|
149
|
-
# The xcframework is at the path `.build/archives/Lottie.xcframework.zip`.
|
|
150
|
-
# GitHub always zips the artifacts before uploading, so if we uploaded the .xframework.zip
|
|
151
|
-
# directly then it would actually upload a double-zip (a .zip containing our `Lottie.xcframework.zip`).
|
|
152
|
-
# This is confusing especially since macOS Archive Utility automatially unzips both layers at once.
|
|
153
|
-
# Instead, we upload the entire archives folder, resulting in an `XCFramework.zip` that unzips
|
|
154
|
-
# to an `archives` directory containing our `Lottie.xcframework.zip`.
|
|
155
|
-
path: .build/archives
|
|
156
|
-
|
|
157
122
|
cocoapod:
|
|
158
123
|
name: "Lint CocoaPods podspec"
|
|
159
124
|
runs-on: macos-13
|
|
@@ -171,7 +136,7 @@ jobs:
|
|
|
171
136
|
strategy:
|
|
172
137
|
matrix:
|
|
173
138
|
xcode:
|
|
174
|
-
- '15.0' # Swift 5.9
|
|
139
|
+
- '15.0' # Swift 5.9
|
|
175
140
|
steps:
|
|
176
141
|
- uses: actions/checkout@v2
|
|
177
142
|
- uses: ./.github/actions/setup
|
|
@@ -330,6 +330,7 @@
|
|
|
330
330
|
0887347B28F0CCDD00458627 /* LottieAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0887347428F0CCDD00458627 /* LottieAnimationView.swift */; };
|
|
331
331
|
0887347C28F0CCDD00458627 /* LottieAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0887347428F0CCDD00458627 /* LottieAnimationView.swift */; };
|
|
332
332
|
0887347D28F0CCDD00458627 /* LottieAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0887347428F0CCDD00458627 /* LottieAnimationView.swift */; };
|
|
333
|
+
089C50C22ABA0C6D007903D3 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 089C50C12ABA0C6D007903D3 /* LoggingTests.swift */; };
|
|
333
334
|
08AB05552A61C20400DE86FD /* ReducedMotionOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08AB05542A61C20400DE86FD /* ReducedMotionOption.swift */; };
|
|
334
335
|
08AB05562A61C20400DE86FD /* ReducedMotionOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08AB05542A61C20400DE86FD /* ReducedMotionOption.swift */; };
|
|
335
336
|
08AB05572A61C20400DE86FD /* ReducedMotionOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08AB05542A61C20400DE86FD /* ReducedMotionOption.swift */; };
|
|
@@ -1176,6 +1177,7 @@
|
|
|
1176
1177
|
0887347228F0CCDD00458627 /* LottieAnimationHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LottieAnimationHelpers.swift; sourceTree = "<group>"; };
|
|
1177
1178
|
0887347328F0CCDD00458627 /* LottieAnimationViewInitializers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LottieAnimationViewInitializers.swift; sourceTree = "<group>"; };
|
|
1178
1179
|
0887347428F0CCDD00458627 /* LottieAnimationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LottieAnimationView.swift; sourceTree = "<group>"; };
|
|
1180
|
+
089C50C12ABA0C6D007903D3 /* LoggingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingTests.swift; sourceTree = "<group>"; };
|
|
1179
1181
|
08AB05542A61C20400DE86FD /* ReducedMotionOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReducedMotionOption.swift; sourceTree = "<group>"; };
|
|
1180
1182
|
08AB05582A61C5B700DE86FD /* DecodingStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodingStrategy.swift; sourceTree = "<group>"; };
|
|
1181
1183
|
08AB055C2A61C5CC00DE86FD /* RenderingEngineOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenderingEngineOption.swift; sourceTree = "<group>"; };
|
|
@@ -1755,6 +1757,7 @@
|
|
|
1755
1757
|
08CB2680291ED2B700B4F071 /* AnimationViewTests.swift */,
|
|
1756
1758
|
2E70F79E295BB6D30089A0EF /* CompatibleAnimationViewTests.swift */,
|
|
1757
1759
|
080F5FDB2AB1075000ADC32C /* TextProviderTests.swift */,
|
|
1760
|
+
089C50C12ABA0C6D007903D3 /* LoggingTests.swift */,
|
|
1758
1761
|
);
|
|
1759
1762
|
path = Tests;
|
|
1760
1763
|
sourceTree = "<group>";
|
|
@@ -3233,6 +3236,7 @@
|
|
|
3233
3236
|
2EAF59A727A076BC00E00531 /* Bundle+Module.swift in Sources */,
|
|
3234
3237
|
2E70F79F295BB6D30089A0EF /* CompatibleAnimationViewTests.swift in Sources */,
|
|
3235
3238
|
2E8044AE27A07347006E74CB /* Snapshotting+presentationLayer.swift in Sources */,
|
|
3239
|
+
089C50C22ABA0C6D007903D3 /* LoggingTests.swift in Sources */,
|
|
3236
3240
|
36E57EAC28AF7ADF00B7EFDA /* HardcodedTextProvider.swift in Sources */,
|
|
3237
3241
|
2E72128527BB32DB0027BC56 /* PerformanceTests.swift in Sources */,
|
|
3238
3242
|
6DB3BDC328245AA2002A276D /* ParsingTests.swift in Sources */,
|
package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate
CHANGED
|
Binary file
|
package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
CHANGED
|
@@ -52,22 +52,6 @@
|
|
|
52
52
|
</Locations>
|
|
53
53
|
</BreakpointContent>
|
|
54
54
|
</BreakpointProxy>
|
|
55
|
-
<BreakpointProxy
|
|
56
|
-
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
57
|
-
<BreakpointContent
|
|
58
|
-
uuid = "7317D33F-83F7-487F-92D8-361AFDC3108F"
|
|
59
|
-
shouldBeEnabled = "No"
|
|
60
|
-
ignoreCount = "0"
|
|
61
|
-
continueAfterRunningActions = "No"
|
|
62
|
-
filePath = "Sources/Private/CoreAnimation/Layers/AnimationLayer.swift"
|
|
63
|
-
startingColumnNumber = "9223372036854775807"
|
|
64
|
-
endingColumnNumber = "9223372036854775807"
|
|
65
|
-
startingLineNumber = "59"
|
|
66
|
-
endingLineNumber = "59"
|
|
67
|
-
landmarkName = "addingKeypathComponent(_:)"
|
|
68
|
-
landmarkType = "7">
|
|
69
|
-
</BreakpointContent>
|
|
70
|
-
</BreakpointProxy>
|
|
71
55
|
<BreakpointProxy
|
|
72
56
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
73
57
|
<BreakpointContent
|
|
@@ -79,8 +63,8 @@
|
|
|
79
63
|
filePath = "Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift"
|
|
80
64
|
startingColumnNumber = "9223372036854775807"
|
|
81
65
|
endingColumnNumber = "9223372036854775807"
|
|
82
|
-
startingLineNumber = "
|
|
83
|
-
endingLineNumber = "
|
|
66
|
+
startingLineNumber = "104"
|
|
67
|
+
endingLineNumber = "104"
|
|
84
68
|
landmarkName = "CALayer"
|
|
85
69
|
landmarkType = "21">
|
|
86
70
|
<Locations>
|
|
@@ -303,6 +287,21 @@
|
|
|
303
287
|
endingLineNumber = "412"
|
|
304
288
|
offsetFromSymbolStart = "127">
|
|
305
289
|
</Location>
|
|
290
|
+
<Location
|
|
291
|
+
uuid = "E5D4F221-8220-42A8-BB35-32D5BEE1328B - 12a91848e5910a61"
|
|
292
|
+
shouldBeEnabled = "Yes"
|
|
293
|
+
ignoreCount = "0"
|
|
294
|
+
continueAfterRunningActions = "No"
|
|
295
|
+
symbolName = "__C.UIView.systemLayoutFittingIntrinsicWidthFixedHeight(_: CoreGraphics.CGFloat, priority: __C.UILayoutPriority) -> __C.CGSize"
|
|
296
|
+
moduleName = "Lottie"
|
|
297
|
+
usesParentBreakpointCondition = "Yes"
|
|
298
|
+
urlString = "file:///Users/calstephens/Documents/lottie/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift"
|
|
299
|
+
startingColumnNumber = "9223372036854775807"
|
|
300
|
+
endingColumnNumber = "9223372036854775807"
|
|
301
|
+
startingLineNumber = "412"
|
|
302
|
+
endingLineNumber = "412"
|
|
303
|
+
offsetFromSymbolStart = "99">
|
|
304
|
+
</Location>
|
|
306
305
|
</Locations>
|
|
307
306
|
</BreakpointContent>
|
|
308
307
|
</BreakpointProxy>
|
|
@@ -412,6 +411,21 @@
|
|
|
412
411
|
endingLineNumber = "393"
|
|
413
412
|
offsetFromSymbolStart = "128">
|
|
414
413
|
</Location>
|
|
414
|
+
<Location
|
|
415
|
+
uuid = "7043C7FC-0028-426B-91A7-E05945E62122 - 94200cadb594d8f7"
|
|
416
|
+
shouldBeEnabled = "Yes"
|
|
417
|
+
ignoreCount = "0"
|
|
418
|
+
continueAfterRunningActions = "No"
|
|
419
|
+
symbolName = "__C.UIView.systemLayoutFittingIntrinsicHeightFixedWidth(_: CoreGraphics.CGFloat, priority: __C.UILayoutPriority) -> __C.CGSize"
|
|
420
|
+
moduleName = "Lottie"
|
|
421
|
+
usesParentBreakpointCondition = "Yes"
|
|
422
|
+
urlString = "file:///Users/calstephens/Documents/lottie/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift"
|
|
423
|
+
startingColumnNumber = "9223372036854775807"
|
|
424
|
+
endingColumnNumber = "9223372036854775807"
|
|
425
|
+
startingLineNumber = "393"
|
|
426
|
+
endingLineNumber = "393"
|
|
427
|
+
offsetFromSymbolStart = "97">
|
|
428
|
+
</Location>
|
|
415
429
|
</Locations>
|
|
416
430
|
</BreakpointContent>
|
|
417
431
|
</BreakpointProxy>
|
|
@@ -525,49 +539,49 @@
|
|
|
525
539
|
<BreakpointProxy
|
|
526
540
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
527
541
|
<BreakpointContent
|
|
528
|
-
uuid = "
|
|
542
|
+
uuid = "93EDC5AB-8948-4148-83CC-FDDCB8BE5AFE"
|
|
529
543
|
shouldBeEnabled = "No"
|
|
530
544
|
ignoreCount = "0"
|
|
531
545
|
continueAfterRunningActions = "No"
|
|
532
546
|
filePath = "Example/Example/AnimationPreviewView.swift"
|
|
533
547
|
startingColumnNumber = "9223372036854775807"
|
|
534
548
|
endingColumnNumber = "9223372036854775807"
|
|
535
|
-
startingLineNumber = "
|
|
536
|
-
endingLineNumber = "
|
|
537
|
-
landmarkName = "
|
|
538
|
-
landmarkType = "
|
|
549
|
+
startingLineNumber = "119"
|
|
550
|
+
endingLineNumber = "119"
|
|
551
|
+
landmarkName = "AnimationPreviewView"
|
|
552
|
+
landmarkType = "14">
|
|
539
553
|
</BreakpointContent>
|
|
540
554
|
</BreakpointProxy>
|
|
541
555
|
<BreakpointProxy
|
|
542
556
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
543
557
|
<BreakpointContent
|
|
544
|
-
uuid = "
|
|
558
|
+
uuid = "6054DF71-1266-422E-9C2F-56F48E5C9F70"
|
|
545
559
|
shouldBeEnabled = "Yes"
|
|
546
560
|
ignoreCount = "0"
|
|
547
561
|
continueAfterRunningActions = "No"
|
|
548
|
-
filePath = "
|
|
562
|
+
filePath = "Sources/Public/iOS/FilepathImageProvider.swift"
|
|
549
563
|
startingColumnNumber = "9223372036854775807"
|
|
550
564
|
endingColumnNumber = "9223372036854775807"
|
|
551
|
-
startingLineNumber = "
|
|
552
|
-
endingLineNumber = "
|
|
553
|
-
landmarkName = "
|
|
554
|
-
landmarkType = "
|
|
565
|
+
startingLineNumber = "40"
|
|
566
|
+
endingLineNumber = "40"
|
|
567
|
+
landmarkName = "imageForAsset(asset:)"
|
|
568
|
+
landmarkType = "7">
|
|
555
569
|
</BreakpointContent>
|
|
556
570
|
</BreakpointProxy>
|
|
557
571
|
<BreakpointProxy
|
|
558
572
|
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
559
573
|
<BreakpointContent
|
|
560
|
-
uuid = "
|
|
561
|
-
shouldBeEnabled = "
|
|
574
|
+
uuid = "8628051F-F131-475B-8FBA-5C9F7B7F9CF8"
|
|
575
|
+
shouldBeEnabled = "Yes"
|
|
562
576
|
ignoreCount = "0"
|
|
563
577
|
continueAfterRunningActions = "No"
|
|
564
|
-
filePath = "
|
|
578
|
+
filePath = "Sources/Private/MainThread/LayerContainers/Utility/LayerImageProvider.swift"
|
|
565
579
|
startingColumnNumber = "9223372036854775807"
|
|
566
580
|
endingColumnNumber = "9223372036854775807"
|
|
567
|
-
startingLineNumber = "
|
|
568
|
-
endingLineNumber = "
|
|
569
|
-
landmarkName = "
|
|
570
|
-
landmarkType = "
|
|
581
|
+
startingLineNumber = "49"
|
|
582
|
+
endingLineNumber = "49"
|
|
583
|
+
landmarkName = "reloadImages()"
|
|
584
|
+
landmarkType = "7">
|
|
571
585
|
</BreakpointContent>
|
|
572
586
|
</BreakpointProxy>
|
|
573
587
|
</Breakpoints>
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ To install Lottie using [Swift Package Manager](https://github.com/apple/swift-p
|
|
|
41
41
|
or you can add the following dependency to your `Package.swift`:
|
|
42
42
|
|
|
43
43
|
```swift
|
|
44
|
-
.package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.3.
|
|
44
|
+
.package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.3.2")
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
When using Swift Package Manager we recommend using the [lottie-spm](https://github.com/airbnb/lottie-spm) repo instead of the main lottie-ios repo. The main git repository for [lottie-ios](https://github.com/airbnb/lottie-ios) is somewhat large (300+ MB), and Swift Package Manager always downloads the full repository with all git history. The [lottie-spm](https://github.com/airbnb/lottie-spm) repo is much smaller (less than 500kb), so can be downloaded much more quickly.
|
|
@@ -50,15 +50,14 @@ extension CALayer {
|
|
|
50
50
|
guard !keyframes.isEmpty else { return nil }
|
|
51
51
|
|
|
52
52
|
// Check if this set of keyframes uses After Effects expressions, which aren't supported.
|
|
53
|
-
|
|
53
|
+
// - We only log this once per `CoreAnimationLayer` instance.
|
|
54
|
+
if keyframeGroup.unsupportedAfterEffectsExpression != nil, !context.loggingState.hasLoggedAfterEffectsExpressionsWarning {
|
|
55
|
+
context.loggingState.hasLoggedAfterEffectsExpressionsWarning = true
|
|
54
56
|
context.logger.info("""
|
|
55
57
|
`\(property.caLayerKeypath)` animation for "\(context.currentKeypath.fullPath)" \
|
|
56
58
|
includes an After Effects expression (https://helpx.adobe.com/after-effects/using/expression-language.html), \
|
|
57
59
|
which is not supported by lottie-ios (expressions are only supported by lottie-web). \
|
|
58
60
|
This animation may not play correctly.
|
|
59
|
-
|
|
60
|
-
\(unsupportedAfterEffectsExpression.replacingOccurrences(of: "\n", with: "\n "))
|
|
61
|
-
|
|
62
61
|
""")
|
|
63
62
|
}
|
|
64
63
|
|
|
@@ -209,6 +209,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
209
209
|
private let valueProviderStore: ValueProviderStore
|
|
210
210
|
private let compatibilityTracker: CompatibilityTracker
|
|
211
211
|
private let logger: LottieLogger
|
|
212
|
+
private let loggingState = LoggingState()
|
|
212
213
|
|
|
213
214
|
/// The current playback state of the animation that is displayed in this layer
|
|
214
215
|
private var currentPlaybackState: PlaybackState? {
|
|
@@ -265,6 +266,7 @@ final class CoreAnimationLayer: BaseAnimationLayer {
|
|
|
265
266
|
valueProviderStore: valueProviderStore,
|
|
266
267
|
compatibilityTracker: compatibilityTracker,
|
|
267
268
|
logger: logger,
|
|
269
|
+
loggingState: loggingState,
|
|
268
270
|
currentKeypath: AnimationKeypath(keys: []),
|
|
269
271
|
textProvider: textProvider,
|
|
270
272
|
recordHierarchyKeypath: configuration.recordHierarchyKeypath)
|
|
@@ -449,7 +451,9 @@ extension CoreAnimationLayer: RootAnimationLayer {
|
|
|
449
451
|
}
|
|
450
452
|
|
|
451
453
|
func forceDisplayUpdate() {
|
|
452
|
-
|
|
454
|
+
// Unimplemented
|
|
455
|
+
// - We can't call `display()` here, because it would cause unexpected frame animations:
|
|
456
|
+
// https://github.com/airbnb/lottie-ios/issues/2193
|
|
453
457
|
}
|
|
454
458
|
|
|
455
459
|
func logHierarchyKeypaths() {
|
|
@@ -38,6 +38,9 @@ struct LayerAnimationContext {
|
|
|
38
38
|
/// The logger that should be used for assertions and warnings
|
|
39
39
|
let logger: LottieLogger
|
|
40
40
|
|
|
41
|
+
/// Mutable state related to log events, stored on the `CoreAnimationLayer`.
|
|
42
|
+
let loggingState: LoggingState
|
|
43
|
+
|
|
41
44
|
/// The AnimationKeypath represented by the current layer
|
|
42
45
|
var currentKeypath: AnimationKeypath
|
|
43
46
|
|
|
@@ -84,3 +87,19 @@ struct LayerAnimationContext {
|
|
|
84
87
|
return copy
|
|
85
88
|
}
|
|
86
89
|
}
|
|
90
|
+
|
|
91
|
+
// MARK: - LoggingState
|
|
92
|
+
|
|
93
|
+
/// Mutable state related to log events, stored on the `CoreAnimationLayer`.
|
|
94
|
+
final class LoggingState {
|
|
95
|
+
|
|
96
|
+
// MARK: Lifecycle
|
|
97
|
+
|
|
98
|
+
init() { }
|
|
99
|
+
|
|
100
|
+
// MARK: Internal
|
|
101
|
+
|
|
102
|
+
/// Whether or not the warning about unsupported After Effects expressions
|
|
103
|
+
/// has been logged yet for this layer.
|
|
104
|
+
var hasLoggedAfterEffectsExpressionsWarning = false
|
|
105
|
+
}
|
|
@@ -107,7 +107,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
107
107
|
guard let animation = animation else { return }
|
|
108
108
|
|
|
109
109
|
defer {
|
|
110
|
-
currentPlaybackMode = .toProgress
|
|
110
|
+
currentPlaybackMode = .playing(.fromProgress(nil, toProgress: 1, loopMode: loopMode))
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
if shouldOverrideWithReducedMotionAnimation {
|
|
@@ -139,7 +139,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
139
139
|
guard let animation = animation else { return }
|
|
140
140
|
|
|
141
141
|
defer {
|
|
142
|
-
currentPlaybackMode = .fromProgress(fromProgress, toProgress: toProgress, loopMode: loopMode ?? self.loopMode)
|
|
142
|
+
currentPlaybackMode = .playing(.fromProgress(fromProgress, toProgress: toProgress, loopMode: loopMode ?? self.loopMode))
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
if shouldOverrideWithReducedMotionAnimation {
|
|
@@ -172,7 +172,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
172
172
|
completion: LottieCompletionBlock? = nil)
|
|
173
173
|
{
|
|
174
174
|
defer {
|
|
175
|
-
currentPlaybackMode = .fromFrame(fromFrame, toFrame: toFrame, loopMode: loopMode ?? self.loopMode)
|
|
175
|
+
currentPlaybackMode = .playing(.fromFrame(fromFrame, toFrame: toFrame, loopMode: loopMode ?? self.loopMode))
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
if shouldOverrideWithReducedMotionAnimation {
|
|
@@ -216,11 +216,11 @@ public class LottieAnimationLayer: CALayer {
|
|
|
216
216
|
completion: LottieCompletionBlock? = nil)
|
|
217
217
|
{
|
|
218
218
|
defer {
|
|
219
|
-
currentPlaybackMode = .fromMarker(
|
|
219
|
+
currentPlaybackMode = .playing(.fromMarker(
|
|
220
220
|
fromMarker,
|
|
221
221
|
toMarker: toMarker,
|
|
222
222
|
playEndMarkerFrame: playEndMarkerFrame,
|
|
223
|
-
loopMode: loopMode ?? self.loopMode)
|
|
223
|
+
loopMode: loopMode ?? self.loopMode))
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
if shouldOverrideWithReducedMotionAnimation {
|
|
@@ -273,7 +273,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
defer {
|
|
276
|
-
currentPlaybackMode = .marker(marker, loopMode: loopMode ?? self.loopMode)
|
|
276
|
+
currentPlaybackMode = .playing(.marker(marker, loopMode: loopMode ?? self.loopMode))
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
if shouldOverrideWithReducedMotionAnimation {
|
|
@@ -311,7 +311,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
311
311
|
guard !markers.isEmpty else { return }
|
|
312
312
|
|
|
313
313
|
defer {
|
|
314
|
-
currentPlaybackMode = .markers(markers)
|
|
314
|
+
currentPlaybackMode = .playing(.markers(markers))
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
if shouldOverrideWithReducedMotionAnimation {
|
|
@@ -357,62 +357,124 @@ public class LottieAnimationLayer: CALayer {
|
|
|
357
357
|
///
|
|
358
358
|
/// The completion closure will be called with `false`
|
|
359
359
|
open func pause() {
|
|
360
|
-
|
|
361
|
-
currentPlaybackMode = .pause
|
|
360
|
+
pause(at: .currentFrame)
|
|
362
361
|
}
|
|
363
362
|
|
|
364
|
-
///
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
363
|
+
/// Pauses the animation at a given state.
|
|
364
|
+
open func pause(at state: LottiePlaybackMode.PausedState) {
|
|
365
|
+
switch state {
|
|
366
|
+
case .currentFrame:
|
|
367
|
+
removeCurrentAnimation()
|
|
368
|
+
|
|
369
|
+
case .progress(let animationProgressTime):
|
|
370
|
+
currentProgress = animationProgressTime
|
|
371
|
+
|
|
372
|
+
case .frame(let animationFrameTime):
|
|
373
|
+
currentFrame = animationFrameTime
|
|
374
|
+
case .time(let timeInterval):
|
|
375
|
+
currentTime = timeInterval
|
|
376
|
+
|
|
377
|
+
case .marker(let name, let position):
|
|
378
|
+
guard let from = animation?.markerMap?[name] else {
|
|
379
|
+
return
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
switch position {
|
|
383
|
+
case .start:
|
|
384
|
+
currentTime = from.frameTime
|
|
385
|
+
case .end:
|
|
386
|
+
currentTime = from.frameTime + from.durationFrameTime
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
currentPlaybackMode = .paused(at: state)
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
@available(*, deprecated, renamed: "setPlaybackMode(_:completion:)", message: "Will be removed in a future major release.")
|
|
369
394
|
open func play(
|
|
370
395
|
_ playbackMode: LottiePlaybackMode,
|
|
371
396
|
animationCompletionHandler: LottieCompletionBlock? = nil)
|
|
397
|
+
{
|
|
398
|
+
setPlaybackMode(playbackMode, completion: animationCompletionHandler)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/// Applies the given `LottiePlaybackMode` to this layer.
|
|
402
|
+
/// - Parameter playbackMode: The playback mode to apply
|
|
403
|
+
/// - Parameter completion: A closure that is called after
|
|
404
|
+
/// an animation triggered by this method completes.
|
|
405
|
+
open func setPlaybackMode(
|
|
406
|
+
_ playbackMode: LottiePlaybackMode,
|
|
407
|
+
completion: LottieCompletionBlock? = nil)
|
|
372
408
|
{
|
|
373
409
|
switch playbackMode {
|
|
410
|
+
case .paused(at: let state):
|
|
411
|
+
pause(at: state)
|
|
412
|
+
|
|
413
|
+
case .playing(let mode):
|
|
414
|
+
play(mode, completion: completion)
|
|
415
|
+
|
|
374
416
|
case .progress(let progress):
|
|
375
|
-
|
|
417
|
+
pause(at: .progress(progress))
|
|
376
418
|
|
|
377
419
|
case .frame(let frame):
|
|
378
|
-
|
|
420
|
+
pause(at: .frame(frame))
|
|
379
421
|
|
|
380
422
|
case .time(let time):
|
|
381
|
-
|
|
423
|
+
pause(at: .time(time))
|
|
382
424
|
|
|
383
425
|
case .pause:
|
|
384
|
-
pause()
|
|
426
|
+
pause(at: .currentFrame)
|
|
427
|
+
|
|
428
|
+
case .fromProgress(let from, let to, let loopMode):
|
|
429
|
+
play(.fromProgress(from, toProgress: to, loopMode: loopMode), completion: completion)
|
|
430
|
+
|
|
431
|
+
case .fromFrame(let from, let to, let loopMode):
|
|
432
|
+
play(.fromFrame(from, toFrame: to, loopMode: loopMode), completion: completion)
|
|
433
|
+
|
|
434
|
+
case .fromMarker(let from, let to, let playEndMarkerFrame, let loopMode):
|
|
435
|
+
play(.fromMarker(from, toMarker: to, playEndMarkerFrame: playEndMarkerFrame, loopMode: loopMode), completion: completion)
|
|
436
|
+
|
|
437
|
+
case .marker(let name, let loopMode):
|
|
438
|
+
play(.marker(name, loopMode: loopMode), completion: completion)
|
|
385
439
|
|
|
386
|
-
case .
|
|
440
|
+
case .markers(let names):
|
|
441
|
+
play(.markers(names), completion: completion)
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/// Applies the given `LottiePlaybackMode` to this layer.
|
|
446
|
+
/// - Parameter playbackMode: The playback mode to apply
|
|
447
|
+
/// - Parameter completion: A closure that is called after
|
|
448
|
+
/// an animation triggered by this method completes.
|
|
449
|
+
open func play(_ playbackMode: LottiePlaybackMode.PlaybackMode, completion: LottieCompletionBlock? = nil) {
|
|
450
|
+
switch playbackMode {
|
|
451
|
+
case .fromProgress(let from, let to, let loopMode):
|
|
387
452
|
play(
|
|
388
|
-
fromProgress:
|
|
389
|
-
toProgress:
|
|
453
|
+
fromProgress: from,
|
|
454
|
+
toProgress: to,
|
|
390
455
|
loopMode: loopMode,
|
|
391
|
-
completion:
|
|
456
|
+
completion: completion)
|
|
392
457
|
|
|
393
|
-
case .fromFrame(let
|
|
458
|
+
case .fromFrame(let from, let to, let loopMode):
|
|
394
459
|
play(
|
|
395
|
-
fromFrame:
|
|
396
|
-
toFrame:
|
|
460
|
+
fromFrame: from,
|
|
461
|
+
toFrame: to,
|
|
397
462
|
loopMode: loopMode,
|
|
398
|
-
completion:
|
|
463
|
+
completion: completion)
|
|
399
464
|
|
|
400
|
-
case .fromMarker(let
|
|
465
|
+
case .fromMarker(let from, let to, let playEndMarkerFrame, let loopMode):
|
|
401
466
|
play(
|
|
402
|
-
fromMarker:
|
|
403
|
-
toMarker:
|
|
467
|
+
fromMarker: from,
|
|
468
|
+
toMarker: to,
|
|
404
469
|
playEndMarkerFrame: playEndMarkerFrame,
|
|
405
470
|
loopMode: loopMode,
|
|
406
|
-
completion:
|
|
471
|
+
completion: completion)
|
|
407
472
|
|
|
408
|
-
case .marker(let
|
|
409
|
-
play(
|
|
410
|
-
marker: marker,
|
|
411
|
-
loopMode: loopMode,
|
|
412
|
-
completion: animationCompletionHandler)
|
|
473
|
+
case .marker(let name, loopMode: let loopMode):
|
|
474
|
+
play(marker: name, loopMode: loopMode, completion: completion)
|
|
413
475
|
|
|
414
|
-
case .markers(let
|
|
415
|
-
play(markers:
|
|
476
|
+
case .markers(let names):
|
|
477
|
+
play(markers: names, completion: completion)
|
|
416
478
|
}
|
|
417
479
|
}
|
|
418
480
|
|
|
@@ -602,7 +664,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
602
664
|
set {
|
|
603
665
|
if let animation = animation {
|
|
604
666
|
currentFrame = animation.frameTime(forProgress: newValue)
|
|
605
|
-
currentPlaybackMode = .progress(newValue)
|
|
667
|
+
currentPlaybackMode = .paused(at: .progress(newValue))
|
|
606
668
|
} else {
|
|
607
669
|
currentFrame = 0
|
|
608
670
|
}
|
|
@@ -624,7 +686,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
624
686
|
set {
|
|
625
687
|
if let animation = animation {
|
|
626
688
|
currentFrame = animation.frameTime(forTime: newValue)
|
|
627
|
-
currentPlaybackMode = .time(newValue)
|
|
689
|
+
currentPlaybackMode = .paused(at: .time(newValue))
|
|
628
690
|
} else {
|
|
629
691
|
currentFrame = 0
|
|
630
692
|
}
|
|
@@ -645,7 +707,7 @@ public class LottieAnimationLayer: CALayer {
|
|
|
645
707
|
set {
|
|
646
708
|
removeCurrentAnimationIfNecessary()
|
|
647
709
|
updateAnimationFrame(newValue)
|
|
648
|
-
currentPlaybackMode = .frame(currentFrame)
|
|
710
|
+
currentPlaybackMode = .paused(at: .frame(currentFrame))
|
|
649
711
|
}
|
|
650
712
|
get {
|
|
651
713
|
rootAnimationLayer?.currentFrame ?? 0
|
|
@@ -219,6 +219,13 @@ open class LottieAnimationView: LottieAnimationViewBase {
|
|
|
219
219
|
|
|
220
220
|
// MARK: Open
|
|
221
221
|
|
|
222
|
+
/// Applies the given `LottiePlaybackMode` to this layer.
|
|
223
|
+
/// - Parameter completion: A closure that is called after
|
|
224
|
+
/// an animation triggered by this method completes.
|
|
225
|
+
open func play(_ mode: LottiePlaybackMode.PlaybackMode, completion: LottieCompletionBlock? = nil) {
|
|
226
|
+
lottieAnimationLayer.play(mode, completion: completion)
|
|
227
|
+
}
|
|
228
|
+
|
|
222
229
|
/// Plays the animation from its current state to the end.
|
|
223
230
|
///
|
|
224
231
|
/// - Parameter completion: An optional completion closure to be called when the animation completes playing.
|
|
@@ -341,16 +348,22 @@ open class LottieAnimationView: LottieAnimationViewBase {
|
|
|
341
348
|
lottieAnimationLayer.pause()
|
|
342
349
|
}
|
|
343
350
|
|
|
344
|
-
|
|
345
|
-
/// - Parameter animationCompletionHandler: A closure that is called after
|
|
346
|
-
/// an animation triggered by this method completes. This completion
|
|
347
|
-
/// handler is **not called** after setting the playback mode to a
|
|
348
|
-
/// mode that doesn't animate (e.g. `progress`, `frame`, `time`, or `pause`).
|
|
351
|
+
@available(*, deprecated, renamed: "setPlaybackMode(_:completion:)", message: "Will be removed in a future major release.")
|
|
349
352
|
open func play(
|
|
350
353
|
_ playbackMode: LottiePlaybackMode,
|
|
351
354
|
animationCompletionHandler: LottieCompletionBlock? = nil)
|
|
352
355
|
{
|
|
353
|
-
lottieAnimationLayer.
|
|
356
|
+
lottieAnimationLayer.setPlaybackMode(playbackMode, completion: animationCompletionHandler)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/// Applies the given `LottiePlaybackMode` to this layer.
|
|
360
|
+
/// - Parameter completion: A closure that is called after
|
|
361
|
+
/// an animation triggered by this method completes.
|
|
362
|
+
open func setPlaybackMode(
|
|
363
|
+
_ playbackMode: LottiePlaybackMode,
|
|
364
|
+
completion: LottieCompletionBlock? = nil)
|
|
365
|
+
{
|
|
366
|
+
lottieAnimationLayer.setPlaybackMode(playbackMode, completion: completion)
|
|
354
367
|
}
|
|
355
368
|
|
|
356
369
|
// MARK: Public
|
|
@@ -794,6 +807,9 @@ open class LottieAnimationView: LottieAnimationViewBase {
|
|
|
794
807
|
|
|
795
808
|
// MARK: Internal
|
|
796
809
|
|
|
810
|
+
// The backing CALayer for this animation view.
|
|
811
|
+
let lottieAnimationLayer: LottieAnimationLayer
|
|
812
|
+
|
|
797
813
|
var animationLayer: RootAnimationLayer? {
|
|
798
814
|
lottieAnimationLayer.rootAnimationLayer
|
|
799
815
|
}
|
|
@@ -1029,8 +1045,5 @@ open class LottieAnimationView: LottieAnimationViewBase {
|
|
|
1029
1045
|
|
|
1030
1046
|
// MARK: Private
|
|
1031
1047
|
|
|
1032
|
-
// The backing CALayer for this animation view.
|
|
1033
|
-
private let lottieAnimationLayer: LottieAnimationLayer
|
|
1034
|
-
|
|
1035
1048
|
private let logger: LottieLogger
|
|
1036
1049
|
}
|
|
@@ -7,91 +7,173 @@ import Foundation
|
|
|
7
7
|
|
|
8
8
|
/// Configuration for how a Lottie animation should be played
|
|
9
9
|
public enum LottiePlaybackMode: Hashable {
|
|
10
|
-
|
|
11
|
-
///
|
|
10
|
+
|
|
11
|
+
/// The animation is paused at the given state (e.g. paused at a specific frame)
|
|
12
|
+
case paused(at: PausedState)
|
|
13
|
+
|
|
14
|
+
/// The animation is playing using the given playback mode (e.g. looping from the start to the end)
|
|
15
|
+
case playing(_ mode: PlaybackMode)
|
|
16
|
+
|
|
17
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.")
|
|
12
18
|
case progress(_ progress: AnimationProgressTime)
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.")
|
|
15
21
|
case frame(_ frame: AnimationFrameTime)
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.")
|
|
18
24
|
case time(_ time: TimeInterval)
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.paused(at:)", message: "Will be removed in a future major release.")
|
|
21
27
|
case pause
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
/// - Parameter fromProgress: The start progress of the animation. If `nil` the animation will start at the current progress.
|
|
25
|
-
/// - Parameter toProgress: The end progress of the animation.
|
|
26
|
-
/// - Parameter loopMode: The loop behavior of the animation.
|
|
29
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
27
30
|
case fromProgress(_ fromProgress: AnimationProgressTime?, toProgress: AnimationProgressTime, loopMode: LottieLoopMode)
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
/// - Parameter fromFrame: The start frame of the animation. If `nil` the animation will start at the current frame.
|
|
31
|
-
/// - Parameter toFrame: The end frame of the animation.
|
|
32
|
-
/// - Parameter loopMode: The loop behavior of the animation.
|
|
32
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
33
33
|
case fromFrame(_ fromFrame: AnimationFrameTime?, toFrame: AnimationFrameTime, loopMode: LottieLoopMode)
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
///
|
|
37
|
-
/// Markers are point in time that are encoded into the Animation data and assigned a name.
|
|
38
|
-
///
|
|
39
|
-
/// NOTE: If markers are not found the play command will exit.
|
|
40
|
-
///
|
|
41
|
-
/// - Parameter fromMarker: The start marker for the animation playback. If `nil` the
|
|
42
|
-
/// animation will start at the current progress.
|
|
43
|
-
/// - Parameter toMarker: The end marker for the animation playback.
|
|
44
|
-
/// - Parameter playEndMarkerFrame: A flag to determine whether or not to play the frame of the end marker. If the
|
|
45
|
-
/// end marker represents the end of the section to play, it should be to true. If the provided end marker
|
|
46
|
-
/// represents the beginning of the next section, it should be false.
|
|
47
|
-
/// - Parameter loopMode: The loop behavior of the animation.
|
|
35
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
48
36
|
case fromMarker(
|
|
49
37
|
_ fromMarker: String?,
|
|
50
38
|
toMarker: String,
|
|
51
39
|
playEndMarkerFrame: Bool = true,
|
|
52
40
|
loopMode: LottieLoopMode)
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
///
|
|
56
|
-
/// A marker is a point in time with an associated duration that is encoded into the
|
|
57
|
-
/// animation data and assigned a name.
|
|
58
|
-
///
|
|
59
|
-
/// NOTE: If marker is not found the play command will exit.
|
|
60
|
-
///
|
|
61
|
-
/// - Parameter marker: The start marker for the animation playback.
|
|
62
|
-
/// - Parameter loopMode: The loop behavior of the animation.
|
|
42
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
63
43
|
case marker(_ marker: String, loopMode: LottieLoopMode)
|
|
64
44
|
|
|
65
|
-
|
|
66
|
-
///
|
|
67
|
-
/// A marker is a point in time with an associated duration that is encoded into the
|
|
68
|
-
/// animation data and assigned a name. Multiple markers can be played sequentially
|
|
69
|
-
/// to create programmable animations.
|
|
70
|
-
///
|
|
71
|
-
/// If a marker is not found, it will be skipped.
|
|
72
|
-
///
|
|
73
|
-
/// If a marker doesn't have a duration value, it will play with a duration of 0
|
|
74
|
-
/// (effectively being skipped).
|
|
75
|
-
///
|
|
76
|
-
/// If another animation is played (by calling any `play` method) while this
|
|
77
|
-
/// marker sequence is playing, the marker sequence will be cancelled.
|
|
78
|
-
///
|
|
79
|
-
/// - Parameter markers: The list of markers to play sequentially.
|
|
45
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
80
46
|
case markers(_ markers: [String])
|
|
47
|
+
|
|
48
|
+
// MARK: Public
|
|
49
|
+
|
|
50
|
+
public enum PausedState: Hashable {
|
|
51
|
+
/// Any existing animation will be paused at the current frame.
|
|
52
|
+
case currentFrame
|
|
53
|
+
|
|
54
|
+
/// The animation is paused at the given progress value,
|
|
55
|
+
/// a value between 0.0 (0% progress) and 1.0 (100% progress).
|
|
56
|
+
case progress(_ progress: AnimationProgressTime)
|
|
57
|
+
|
|
58
|
+
/// The animation is paused at the given frame of the animation.
|
|
59
|
+
case frame(_ frame: AnimationFrameTime)
|
|
60
|
+
|
|
61
|
+
/// The animation is paused at the given time value from the start of the animation.
|
|
62
|
+
case time(_ time: TimeInterval)
|
|
63
|
+
|
|
64
|
+
/// Pauses the animation at a given marker and position
|
|
65
|
+
case marker(_ name: String, position: LottieMarkerPosition = .start)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public enum PlaybackMode: Hashable {
|
|
69
|
+
/// Plays the animation from a progress (0-1) to a progress (0-1).
|
|
70
|
+
/// - Parameter fromProgress: The start progress of the animation. If `nil` the animation will start at the current progress.
|
|
71
|
+
/// - Parameter toProgress: The end progress of the animation.
|
|
72
|
+
/// - Parameter loopMode: The loop behavior of the animation.
|
|
73
|
+
case fromProgress(
|
|
74
|
+
_ fromProgress: AnimationProgressTime?,
|
|
75
|
+
toProgress: AnimationProgressTime,
|
|
76
|
+
loopMode: LottieLoopMode)
|
|
77
|
+
|
|
78
|
+
/// The animation plays from the given `fromFrame` to the given `toFrame`.
|
|
79
|
+
/// - Parameter fromFrame: The start frame of the animation. If `nil` the animation will start at the current frame.
|
|
80
|
+
/// - Parameter toFrame: The end frame of the animation.
|
|
81
|
+
/// - Parameter loopMode: The loop behavior of the animation.
|
|
82
|
+
case fromFrame(
|
|
83
|
+
_ fromFrame: AnimationFrameTime?,
|
|
84
|
+
toFrame: AnimationFrameTime,
|
|
85
|
+
loopMode: LottieLoopMode)
|
|
86
|
+
|
|
87
|
+
/// Plays the animation from a named marker to another marker.
|
|
88
|
+
///
|
|
89
|
+
/// Markers are point in time that are encoded into the Animation data and assigned a name.
|
|
90
|
+
///
|
|
91
|
+
/// NOTE: If markers are not found the play command will exit.
|
|
92
|
+
///
|
|
93
|
+
/// - Parameter fromMarker: The start marker for the animation playback. If `nil` the
|
|
94
|
+
/// animation will start at the current progress.
|
|
95
|
+
/// - Parameter toMarker: The end marker for the animation playback.
|
|
96
|
+
/// - Parameter playEndMarkerFrame: A flag to determine whether or not to play the frame of the end marker. If the
|
|
97
|
+
/// end marker represents the end of the section to play, it should be to true. If the provided end marker
|
|
98
|
+
/// represents the beginning of the next section, it should be false.
|
|
99
|
+
/// - Parameter loopMode: The loop behavior of the animation.
|
|
100
|
+
case fromMarker(
|
|
101
|
+
_ fromMarker: String?,
|
|
102
|
+
toMarker: String,
|
|
103
|
+
playEndMarkerFrame: Bool = true,
|
|
104
|
+
loopMode: LottieLoopMode)
|
|
105
|
+
|
|
106
|
+
/// Plays the animation from a named marker to the end of the marker's duration.
|
|
107
|
+
///
|
|
108
|
+
/// A marker is a point in time with an associated duration that is encoded into the
|
|
109
|
+
/// animation data and assigned a name.
|
|
110
|
+
///
|
|
111
|
+
/// NOTE: If marker is not found the play command will exit.
|
|
112
|
+
///
|
|
113
|
+
/// - Parameter marker: The start marker for the animation playback.
|
|
114
|
+
/// - Parameter loopMode: The loop behavior of the animation.
|
|
115
|
+
case marker(
|
|
116
|
+
_ marker: String,
|
|
117
|
+
loopMode: LottieLoopMode)
|
|
118
|
+
|
|
119
|
+
/// Plays the given markers sequentially in order.
|
|
120
|
+
///
|
|
121
|
+
/// A marker is a point in time with an associated duration that is encoded into the
|
|
122
|
+
/// animation data and assigned a name. Multiple markers can be played sequentially
|
|
123
|
+
/// to create programmable animations.
|
|
124
|
+
///
|
|
125
|
+
/// If a marker is not found, it will be skipped.
|
|
126
|
+
///
|
|
127
|
+
/// If a marker doesn't have a duration value, it will play with a duration of 0
|
|
128
|
+
/// (effectively being skipped).
|
|
129
|
+
///
|
|
130
|
+
/// If another animation is played (by calling any `play` method) while this
|
|
131
|
+
/// marker sequence is playing, the marker sequence will be cancelled.
|
|
132
|
+
///
|
|
133
|
+
/// - Parameter markers: The list of markers to play sequentially.
|
|
134
|
+
case markers(_ markers: [String])
|
|
135
|
+
}
|
|
136
|
+
|
|
81
137
|
}
|
|
82
138
|
|
|
83
139
|
extension LottiePlaybackMode {
|
|
140
|
+
public static var paused: Self {
|
|
141
|
+
.paused(at: .currentFrame)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
145
|
+
public static func toProgress(_ toProgress: AnimationProgressTime, loopMode: LottieLoopMode) -> LottiePlaybackMode {
|
|
146
|
+
.playing(.fromProgress(nil, toProgress: toProgress, loopMode: loopMode))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
150
|
+
public static func toFrame(_ toFrame: AnimationFrameTime, loopMode: LottieLoopMode) -> LottiePlaybackMode {
|
|
151
|
+
.playing(.fromFrame(nil, toFrame: toFrame, loopMode: loopMode))
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@available(*, deprecated, renamed: "LottiePlaybackMode.playing(_:)", message: "Will be removed in a future major release.")
|
|
155
|
+
public static func toMarker(
|
|
156
|
+
_ toMarker: String,
|
|
157
|
+
playEndMarkerFrame: Bool = true,
|
|
158
|
+
loopMode: LottieLoopMode)
|
|
159
|
+
-> LottiePlaybackMode
|
|
160
|
+
{
|
|
161
|
+
.playing(.fromMarker(nil, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: loopMode))
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
extension LottiePlaybackMode.PlaybackMode {
|
|
84
166
|
/// Plays the animation from the current progress to a progress value (0-1).
|
|
85
167
|
/// - Parameter toProgress: The end progress of the animation.
|
|
86
168
|
/// - Parameter loopMode: The loop behavior of the animation.
|
|
87
|
-
public static func toProgress(_ toProgress: AnimationProgressTime, loopMode: LottieLoopMode) ->
|
|
169
|
+
public static func toProgress(_ toProgress: AnimationProgressTime, loopMode: LottieLoopMode) -> Self {
|
|
88
170
|
.fromProgress(nil, toProgress: toProgress, loopMode: loopMode)
|
|
89
171
|
}
|
|
90
172
|
|
|
91
173
|
// Plays the animation from the current frame to the given frame.
|
|
92
174
|
/// - Parameter toFrame: The end frame of the animation.
|
|
93
175
|
/// - Parameter loopMode: The loop behavior of the animation.
|
|
94
|
-
public static func toFrame(_ toFrame: AnimationFrameTime, loopMode: LottieLoopMode) ->
|
|
176
|
+
public static func toFrame(_ toFrame: AnimationFrameTime, loopMode: LottieLoopMode) -> Self {
|
|
95
177
|
.fromFrame(nil, toFrame: toFrame, loopMode: loopMode)
|
|
96
178
|
}
|
|
97
179
|
|
|
@@ -110,8 +192,16 @@ extension LottiePlaybackMode {
|
|
|
110
192
|
_ toMarker: String,
|
|
111
193
|
playEndMarkerFrame: Bool = true,
|
|
112
194
|
loopMode: LottieLoopMode)
|
|
113
|
-
->
|
|
195
|
+
-> Self
|
|
114
196
|
{
|
|
115
197
|
.fromMarker(nil, toMarker: toMarker, playEndMarkerFrame: playEndMarkerFrame, loopMode: loopMode)
|
|
116
198
|
}
|
|
117
199
|
}
|
|
200
|
+
|
|
201
|
+
// MARK: - LottieMarkerPosition
|
|
202
|
+
|
|
203
|
+
/// The position within a marker.
|
|
204
|
+
public enum LottieMarkerPosition: Hashable {
|
|
205
|
+
case start
|
|
206
|
+
case end
|
|
207
|
+
}
|
|
@@ -140,7 +140,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
|
|
|
140
140
|
let playbackMode = playbackMode,
|
|
141
141
|
playbackMode != context.view.currentPlaybackMode
|
|
142
142
|
{
|
|
143
|
-
context.view.
|
|
143
|
+
context.view.setPlaybackMode(playbackMode, completion: animationCompletionHandler)
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
.configurations(configurations)
|
|
@@ -175,27 +175,47 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
|
|
|
175
175
|
return copy
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
@available(*, deprecated, renamed: "playing()", message: "Will be removed in a future major release.")
|
|
179
179
|
public func play() -> Self {
|
|
180
|
-
|
|
180
|
+
playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce)))
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
/// Returns a copy of this view that loops its animation from the start to end whenever visible
|
|
184
184
|
public func looping() -> Self {
|
|
185
|
-
|
|
185
|
+
playbackMode(.playing(.fromProgress(0, toProgress: 1, loopMode: .loop)))
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
|
|
189
|
-
/// with the given `LottiePlaybackMode`.
|
|
188
|
+
@available(*, deprecated, renamed: "playing(_:)", message: "Will be removed in a future major release.")
|
|
190
189
|
public func play(loopMode: LottieLoopMode = .playOnce) -> Self {
|
|
191
|
-
|
|
190
|
+
playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: loopMode)))
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
|
|
193
|
+
@available(*, deprecated, renamed: "playbackMode(_:)", message: "Will be removed in a future major release.")
|
|
195
194
|
public func play(_ playbackMode: LottiePlaybackMode) -> Self {
|
|
196
195
|
self.playbackMode(playbackMode)
|
|
197
196
|
}
|
|
198
197
|
|
|
198
|
+
/// Returns a copy of this view playing with the given playback mode
|
|
199
|
+
public func playing(_ mode: LottiePlaybackMode.PlaybackMode) -> Self {
|
|
200
|
+
playbackMode(.playing(mode))
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/// Returns a copy of this view playing from the current frame to the end frame,
|
|
204
|
+
/// with the given `LottiePlaybackMode`.
|
|
205
|
+
public func playing(loopMode: LottieLoopMode) -> Self {
|
|
206
|
+
playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: loopMode)))
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Returns a copy of this view playing once from the current frame to the end frame
|
|
210
|
+
public func playing() -> Self {
|
|
211
|
+
playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce)))
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Returns a copy of this view paused with the given state
|
|
215
|
+
public func paused(at state: LottiePlaybackMode.PausedState = .currentFrame) -> Self {
|
|
216
|
+
playbackMode(.paused(at: state))
|
|
217
|
+
}
|
|
218
|
+
|
|
199
219
|
/// Returns a copy of this view using the given `LottiePlaybackMode`
|
|
200
220
|
public func playbackMode(_ playbackMode: LottiePlaybackMode) -> Self {
|
|
201
221
|
var copy = self
|
|
@@ -332,7 +352,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
|
|
|
332
352
|
public func currentProgress(_ currentProgress: AnimationProgressTime?) -> Self {
|
|
333
353
|
guard let currentProgress = currentProgress else { return self }
|
|
334
354
|
var copy = self
|
|
335
|
-
copy.playbackMode = .progress(currentProgress)
|
|
355
|
+
copy.playbackMode = .paused(at: .progress(currentProgress))
|
|
336
356
|
return copy
|
|
337
357
|
}
|
|
338
358
|
|
|
@@ -344,7 +364,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
|
|
|
344
364
|
public func currentFrame(_ currentFrame: AnimationFrameTime?) -> Self {
|
|
345
365
|
guard let currentFrame = currentFrame else { return self }
|
|
346
366
|
var copy = self
|
|
347
|
-
copy.playbackMode = .frame(currentFrame)
|
|
367
|
+
copy.playbackMode = .paused(at: .frame(currentFrame))
|
|
348
368
|
return copy
|
|
349
369
|
}
|
|
350
370
|
|
|
@@ -356,7 +376,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
|
|
|
356
376
|
public func currentTime(_ currentTime: TimeInterval?) -> Self {
|
|
357
377
|
guard let currentTime = currentTime else { return self }
|
|
358
378
|
var copy = self
|
|
359
|
-
copy.playbackMode = .time(currentTime)
|
|
379
|
+
copy.playbackMode = .paused(at: .time(currentTime))
|
|
360
380
|
return copy
|
|
361
381
|
}
|
|
362
382
|
|
|
@@ -193,8 +193,10 @@ public final class CompatibleAnimationView: UIView {
|
|
|
193
193
|
commonInit()
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
required init?(coder
|
|
197
|
-
|
|
196
|
+
required init?(coder: NSCoder) {
|
|
197
|
+
animationView = LottieAnimationView()
|
|
198
|
+
super.init(coder: coder)
|
|
199
|
+
commonInit()
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
// MARK: Public
|
package/lottie-ios.podspec
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
Pod::Spec.new do |s|
|
|
10
10
|
s.name = 'lottie-ios'
|
|
11
|
-
s.version = '4.3.
|
|
11
|
+
s.version = '4.3.2'
|
|
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.
|
|
25
|
+
s.swift_version = '5.6'
|
|
26
26
|
s.ios.deployment_target = '11.0'
|
|
27
27
|
s.osx.deployment_target = '10.12'
|
|
28
28
|
s.tvos.deployment_target = '11.0'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lottie-ios",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.2",
|
|
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": {
|