Skip to content

Commit

Permalink
Fix issue where animation size could be incorrect after loading async…
Browse files Browse the repository at this point in the history
… animation (airbnb#2379)
  • Loading branch information
calda authored and Igor Moroz committed May 22, 2024
1 parent 9641152 commit 1204e64
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 13 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
matrix:
xcode:
- '15.2' # Swift 5.9
- '15.3' # Swift 5.10
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/setup
Expand All @@ -49,7 +50,7 @@ jobs:
- uses: actions/checkout@v2
- uses: ./.github/actions/setup
with:
xcode: '15.2' # Swift 5.9
xcode: '15.3' # Swift 5.10
- name: Build Example
run: bundle exec rake build:example:all

Expand All @@ -60,7 +61,7 @@ jobs:
- uses: actions/checkout@v2
- uses: ./.github/actions/setup
with:
xcode: '15.2' # Swift 5.9
xcode: '15.3' # Swift 5.10
- name: Test Package
run: bundle exec rake test:package
- name: Process test artifacts
Expand Down Expand Up @@ -150,7 +151,7 @@ jobs:
strategy:
matrix:
xcode:
- '15.2' # Swift 5.9, first Xcode version with visionOS
- '15.3' # Swift 5.10
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/setup
Expand All @@ -166,7 +167,7 @@ jobs:
strategy:
matrix:
xcode:
- '15.2' # Swift 5.9
- '15.3' # Swift 5.10
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/setup
Expand All @@ -185,7 +186,7 @@ jobs:
with:
install-mint: true
install-carthage: true
xcode: '15.2' # Swift 5.9
xcode: '15.3' # Swift 5.10
- name: Test Carthage support
run: bundle exec rake test:carthage

Expand Down
10 changes: 8 additions & 2 deletions Example/Example/AnimationListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct AnimationListView: View {
Text(item.name)
}

case .animationList, .controlsDemo, .swiftUIInteroperability:
case .animationList, .controlsDemo, .swiftUIInteroperability, .lottieViewLayoutDemo:
Text(item.name)
.frame(height: 50)
}
Expand All @@ -52,6 +52,8 @@ struct AnimationListView: View {
ControlsDemoView()
case .swiftUIInteroperability:
SwiftUIInteroperabilityDemoView()
case .lottieViewLayoutDemo:
LottieViewLayoutDemoView()
}
}
}
Expand All @@ -72,7 +74,7 @@ struct AnimationListView: View {
guard let url = urls.first else { return nil }
return await LottieAnimation.loadedFrom(url: url)?.animationSource

case .animationList, .controlsDemo, .swiftUIInteroperability:
case .animationList, .controlsDemo, .swiftUIInteroperability, .lottieViewLayoutDemo:
return nil
}
}
Expand Down Expand Up @@ -104,6 +106,7 @@ extension AnimationListView {
case remoteAnimations(name: String, urls: [URL])
case controlsDemo
case swiftUIInteroperability
case lottieViewLayoutDemo
}

var items: [Item] {
Expand Down Expand Up @@ -159,6 +162,7 @@ extension AnimationListView {
.animationList(.remoteAnimationsDemo),
.controlsDemo,
.swiftUIInteroperability,
.lottieViewLayoutDemo,
]
}
}
Expand All @@ -174,6 +178,8 @@ extension AnimationListView.Item {
return "Controls Demo"
case .swiftUIInteroperability:
return "SwiftUI Interoperability Demo"
case .lottieViewLayoutDemo:
return "LottieView Layout Demo"
}
}
}
Expand Down
15 changes: 13 additions & 2 deletions Example/Example/LottieViewLayoutDemoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import Lottie
import SwiftUI

struct ContentView: View {
struct LottieViewLayoutDemoView: View {
var body: some View {
HStack {
VStack {
Expand Down Expand Up @@ -35,7 +35,18 @@ struct ContentView: View {
LottieView(animation: .named("Samples/LottieLogo1"))
.looping()

Text("intrinsic content size")
Text("automatic size")
}

VStack {
LottieView {
try await Task.sleep(for: .seconds(1))
return LottieAnimation.named("Samples/LottieLogo1")
}
.intrinsicSize()
.looping()

Text("intrinsic size, async")
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
Expand Down
23 changes: 19 additions & 4 deletions Sources/Public/Animation/LottieView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
}
.sizing(sizing)
.configure { context in
applyCurrentAnimationConfiguration(to: context.view)
applyCurrentAnimationConfiguration(to: context.view, in: context.container)
}
.configurations(configurations)
.opacity(animationSource == nil ? 0 : 1)
Expand All @@ -152,14 +152,22 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
return copy
}

/// Returns a copy of this view that can be resized by scaling its animation to fit the size
/// offered by its parent.
/// Returns a copy of this view that can be resized by scaling its animation
/// to always fit the size offered by its parent.
public func resizable() -> Self {
var copy = self
copy.sizing = .proposed
return copy
}

/// Returns a copy of this view that adopts the intrinsic size of the animation,
/// up to the proposed size.
public func intrinsicSize() -> Self {
var copy = self
copy.sizing = .intrinsic
return copy
}

@available(*, deprecated, renamed: "playing()", message: "Will be removed in a future major release.")
public func play() -> Self {
playbackMode(.playing(.fromProgress(nil, toProgress: 1, loopMode: .playOnce)))
Expand Down Expand Up @@ -501,7 +509,10 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
}

/// Applies playback configuration for the current animation to the `LottieAnimationView`
private func applyCurrentAnimationConfiguration(to view: LottieAnimationView) {
private func applyCurrentAnimationConfiguration(
to view: LottieAnimationView,
in container: SwiftUIMeasurementContainer<LottieAnimationView>)
{
guard let animationSource else { return }
var imageProviderConfiguration = imageProviderConfiguration
var playbackMode = playbackMode
Expand Down Expand Up @@ -543,6 +554,10 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
if animationSource.animation !== view.animation {
view.loadAnimation(animationSource)
animationDidLoad?(animationSource)

// Invalidate the intrinsic size of the SwiftUI measurement container,
// since any cached measurements will be out of date after updating the animation.
container.invalidateIntrinsicContentSize()
}

if
Expand Down

0 comments on commit 1204e64

Please sign in to comment.