I have a LottieAnimationView
along with some other components inside ScrollView
, animation is only supposed to play once.
@State var messageBannerVisisbility: Bool = false
var body: some View {
VStack(alignment: .center) {
TrackableScrollView {
VStack(alignment: .center) {
headerView(components: header)
contentView(components: body)
}
} onScrollingStarted: {
hideMessageBanner()
} onScrollingFinished: {
showMessageBanner()
}
.animation(nil)
footerView(footer: content.footer)
}
.onAppear {
showMessageBanner()
}
}
@ViewBuilder private func footerView(footer: SignupPageV2Footer) -> some View {
VStack(alignment: .leading, spacing: 0) {
if let message = footer.message, messageBannerVisisbility {
footerMessageView(from: message)
}
HStack(alignment: .center, spacing: 8) {
Label(footer.signupAction.info.stripHTMLTags)
.textColor(.secondary)
.frame(width: 115, alignment: .leading)
LozengeButton(title: footer.signupAction.label, isLoading: $viewModel.isPaymentInProgress) {
viewModel.startPayment()
}
.accessibility(identifier: "subscribe_button")
}
.padding([.horizontal, .top], 16)
.padding(.bottom, 8)
.background(Color.white)
}
.background(Color.white.edgesIgnoringSafeArea(.bottom).elevation(.LightBackground.small))
}
@ViewBuilder private func footerMessageView(from message: SignupPageV2FooterMessage) -> some View {
message.build { deeplink in
viewModel.handleDeeplink(deeplink)
} processEvent: { event in
viewModel.handleEvent(event)
}
.transition(.move(edge: .bottom).combined(with: .opacity))
}
private func showMessageBanner() {
if messageBannerVisisbility == true { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
withAnimation(.easeIn(duration: 0.3)) {
messageBannerVisisbility = true
}
}
}
private func hideMessageBanner() {
if messageBannerVisisbility == false { return }
withAnimation(.easeIn(duration: 0.3)) {
messageBannerVisisbility = false
}
}
TrackableScrollView
is my custom implementation to have scroll Start and End callbacks to show/hide footerMessageView
, which is inside footerView
, while scrolling.
The issue I am facing is, whenever I scroll LottieAnimationView seems to be resetting and therefore it plays the animation again everytime I scroll.
How do I just update footerView
so that animation is only played once after the screen loads?
2
Answers
I have seen similar problems and I have been able to solve them by using an id on the view that is supposed to animate only once.
The best way is to add the id as something that is unique to that instance of the view, normally the id would be based on the data you give the view.
This will prevent the view from being re-drawn when there are changes in other components.
Try this:
(I cannot check this code will work or not)