I'm trying to switch the animation played in a Lottie AnimationView using SwiftUI, however nothing seems to happen, despite the code being called during runtime as expected. It looks like when the AnimationView is in the same hierarchy in the view, it doesn't reload. Not sure if it is related to the fact that the AnimationView is loaded through a UIViewRepresentable or not. For example, the follow code does not work:
var body: some View {
if state == .ok {
return AnyView(okView)
} else {
return AnyView(errorView)
}
}
var okView: some View {
ZStack {
LottieView(name: "ok_animation"), loopMode: .loop)
VStack {
Text("Everything is ok!")
}
}
}
var errorView: some View {
ZStack {
LottieView(name: "error_animation"), loopMode: .loop)
VStack {
Text("Something went wrong")
}
}
}
But if I change the hierarchy of the okView/errorView, for example move the LottieView inside the VStack, then the animation updates as expected when I switch views.
This is the LottieView implementation I use:
struct LottieView: UIViewRepresentable {
@State var name: String
var loopMode: LottieLoopMode = .playOnce
var animationView = AnimationView()
func makeUIView(context: UIViewRepresentableContext<LottieView>) -> UIView {
let view = UIView()
animationView.animation = Animation.named(name)
animationView.contentMode = .scaleAspectFill
animationView.loopMode = .loop
animationView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(animationView)
NSLayoutConstraint.activate([
animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
])
return view
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<LottieView>) {
animationView.play()
}
}