SwiftUIでLottieのAnimationViewを使う
はじめに
SwiftUIは始めた手でしたがUIViewRepresentable使えば良いということを知っていたので簡単にできると思っていたんですが、そのままだとうまくいかなかったのでメモとして残します。
SwiftUI側の問題のような気がするんですが、bodyの中で定義してframeを指定した時にmakeUIViewでそのままAnimationViewを渡しているとサイズ指定が効かなくなります。
ダメな例
当初以下のコードのようにLottieのAnimationViewを移行させました。
ググって一番上に日本語で出る記事を流用したものでしたがこちらのコードだと問題が発生します。
このままだとサイズ指定ができず画面幅いっぱいになってしまいサイズ指定をしてもLottieAnimationViewのサイズが変わりません。
import SwiftUI
import Lottie
struct LottieAnimationView: UIViewRepresentable {
let name: String
let loopMode: LottieLoopMode
func makeUIView(context: Context) -> AnimationView {
let view = AnimationView(name: name, bundle: Bundle.main)
view.isUserInteractionEnabled = false
view.loopMode = loopMode
view.play()
return view
}
func updateUIView(_ uiView: AnimationView, context: Context) {}
}
struct ContentView: View {
var body: some View {
LottieAnimationView(name: "animation-name", loopMode: .loop)
.frame(width: 250, height: 250)
}
}
正しい例
はっきりとした理由はわかっていないんですが、以下のようにViewを噛ませる形で作ってやることでSwiftUI上でのframe指定が効くようになりました。
import SwiftUI
import Lottie
struct LottieAnimationView: UIViewRepresentable {
let name: String
let loopMode: LottieLoopMode
var animationView = AnimationView()
func makeUIView(context: UIViewRepresentableContext<LottieAnimationView>) -> UIView {
let view = UIView(frame: .zero)
animationView.animation = Animation.named(name)
animationView.contentMode = .scaleAspectFit
animationView.loopMode = loopMode
animationView.play()
animationView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(animationView)
NSLayoutConstraint.activate([
animationView.heightAnchor.constraint(equalTo: view.heightAnchor),
animationView.widthAnchor.constraint(equalTo: view.widthAnchor)
])
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
struct ContentView: View {
var body: some View {
LottieAnimationView(name: "animation-name", loopMode: .loop)
.frame(width: 250, height: 250)
}
}