我在做动画.它有一堆围巾,上面有Lottie动画.CardStack号牌库用于卡片,Lottie号牌用于彩票.
在CardStack库中,配置参数设置为显示2张卡(当前和下一张),但尽管如此,只有在视图更改状态时才会释放内存.
内存一直累积到最后一张卡.
相应地,如果100张卡到达,那么就会有麻烦.最重要的是,没有内存泄漏.
我用Lottie库try 了各种加速器,但都没有帮助.
我至少应该朝哪个方向看,以免浪费那么多内存?在其他操作系统上一切正常,所以问题不在动画上.
下面是来自UIViewRepresentable
的代码:
struct CustomLottieView: UIViewRepresentable {
enum LoadingType {
case url(URL)
case data(DataResource)
}
let type: LoadingType
let isPaused: Bool
let card: CardModel?
let animationView = LottieAnimationView()
let transition: BoundCardType?
init(type: LoadingType, isPaused: Bool = false, card: CardModel? = nil, transition: BoundCardType? = nil) {
self.isPaused = isPaused
self.type = type
self.card = card
self.transition = transition
}
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
switch type {
case .url(let url):
LottieAnimation.loadedFrom(url: url) { animation in
animationView.animation = animation
isPaused ? nil : animationView.play()
animationView.loopMode = .loop
if let skillCardModel = card as? SkillCardModel {
animationView.play(marker: String(skillCardModel.currentLevelIndex + 1))
}
}
case .data(let data):
animationView.animation = .named(data.name, bundle: data.bundle)
if let skillCardModel = card as? SkillCardModel {
animationView.play(marker: String(skillCardModel.currentLevelIndex + 1))
}
}
animationView.contentMode = .scaleAspectFit
animationView.play()
view.addSubview(animationView)
animationView.translatesAutoresizingMaskIntoConstraints = false
animationView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
animationView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
if isPaused {
context.coordinator.parent.animationView.pause()
} else {
if let skillCardModel = card as? SkillCardModel {
if !context.coordinator.parent.animationView.isAnimationPlaying || animationView.animation == nil {
context.coordinator.parent.animationView.play(marker: String(skillCardModel.currentLevelIndex + 1))
} else {
withAnimation {
var transitionMarker = ""
if let transition = transition {
switch transition {
case .left:
transitionMarker = context.coordinator.parent.animationView.animation?.markerNames.first(where: { $0.contains(">\(skillCardModel.currentLevelIndex + 2)") }) ?? ""
context.coordinator.parent.animationView.play(fromMarker: String(skillCardModel.currentLevelIndex + 2), toMarker: transitionMarker, loopMode: .playOnce)
case .right:
transitionMarker = context.coordinator.parent.animationView.animation?.markerNames.first(where: { $0.contains("\(skillCardModel.currentLevelIndex)>") }) ?? ""
context.coordinator.parent.animationView.play(fromMarker: transitionMarker, toMarker: String(skillCardModel.currentLevelIndex + 1), loopMode: .playOnce)
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
context.coordinator.parent.animationView.play(marker: String(skillCardModel.currentLevelIndex + 1), loopMode: .loop)
}
}
}
} else {
context.coordinator.parent.animationView.play()
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(parent: self)
}
struct Coordinator {
var parent: CustomLottieView
}
}