This is the simplified code as below:
@objc class MySpineModel: NSObject {
var controller: SpineController
var drawable: SkeletonDrawableWrapper?
private var customSkin: Skin?
override init() {
controller = SpineController(
onInitialized: { controller in
controller.animationState.setAnimationByName(
trackIndex: 0,
animationName: "idle",
loop: true
)
},
disposeDrawableOnDeInit: false
)
}
deinit {
controller.animationState.clearTracks()
drawable?.dispose()
customSkin?.dispose()
}
private func toggleSkin(skinName: String, drawable: SkeletonDrawableWrapper) {
customSkin?.dispose()
customSkin = Skin.create(name: "custom-skin")
if let nemSkin = drawable.skeletonData.findSkin(name: skinName) {
customSkin?.addSkin(other: nemSkin)
drawable.skeleton.skin = customSkin
drawable.skeleton.setToSetupPose()
}
}
func loadDrawableData(atlasFileName: String, skeletonFileName: String) async {
guard let drawable = try? await SkeletonDrawableWrapper.fromBundle(
atlasFileName: atlasFileName,
skeletonFileName: skeletonFileName
) else { return }
self.toggleSkin(skinName: "01", drawable: drawable)
self.drawable = drawable
}
func updateAnimation(_ animation: UMIAgentSpineAnimation) {
guard let dw = drawable else { return }
controller.animationState.clearTracks()
controller.animationState.setAnimationByName(trackIndex: 0, animationName: animation.name, loop: animation.canLoop)
}
}
@objc class MySpineView: UIView {
private var spineUIView: SpineUIView?
private var model = MySpineModel()
@objc func loadData(atlasFileName: String, skeletonFileName: String) async {
await model.loadDrawableData(atlasFileName: atlasFileName, skeletonFileName: skeletonFileName)
if let drawable = model.drawable {
spineUIView = SpineUIView(
from: .drawable(drawable),
controller: model.controller,
mode: .fit,
alignment: .center,
boundsProvider: SkinAndAnimationBounds(skins: ["01"]),
backgroundColor: .clear
)
if let spineUIView = spineUIView {
addSubview(spineUIView)
spineUIView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
}
@objc func updateAnimation(_ animation: UMIAgentSpineAnimation) {
guard let _ = model.controller.drawable else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
self?.updateAnimation(animation)
}
return
}
model.updateAnimation(animation)
}
}
After removing MySpineView from superView, I set the instance = nil, then it crashed.