Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue where animation size could be incorrect after loading async animation #2379

Merged
merged 3 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading