崩溃信息如下:

这是我的代码,如下:
class TTSpinePetView: UIView {
var spineView: SpineUIView?
var controller: SpineController?
var customSkin: Skin?
var drawable: SkeletonDrawableWrapper?
var allAnimations: [String] = []
var allSkinsName: [String] = []
var spineSize: CGSize?
var petModel: TTPetModel?
var isInitialized: Bool = false


convenience init() {
    self.init(frame: .zero)
}

func setupView(model: TTPetModel?, size: CGSize?) {
    
    guard let model = model else {
        return
    }
    
    guard let size = size else {
        return
    }
    
    if (model.finalSlots.count ?? 0) < 1 {
        return
    }
    
    if String.isEmpty(model.animation) {
        return
    }
    
    self.petModel = model
    self.spineSize = size
    
    // 初始化 Spine 控制器
    controller = SpineController(
        onInitialized: {[weak self] controller in
            guard let self = self else {
                return
            }
            if self.allAnimations.contains(model.animation)  {
                controller.animationState.setAnimationByName(
                    trackIndex: 0,
                    animationName: model.animation,
                    loop: true
                )
            }
            self.isInitialized = true
        },
        disposeDrawableOnDeInit: false
    )

    let loadDrawable: () async throws -> SkeletonDrawableWrapper = {
        if let atlasUrl = self.findSpinePath(fileName: "cat.atlas"), let skelUrl = self.findSpinePath(fileName: "cat.skel") {
            return try await SkeletonDrawableWrapper.fromFile(atlasFile: atlasUrl, skeletonFile: skelUrl)
        } else {
            let bundle = Bundle.load(with: TTSpinePetView.self, bundleName: "TTUI")
            return try await SkeletonDrawableWrapper.fromBundle(atlasFileName: "cat.atlas", skeletonFileName: "cat.skel", bundle: bundle ?? Bundle.main)
        }
    }
    guard let controller = self.controller else {
        return
    }
    
    Task.detached(priority: .high) {
        do {
            let drawable = try await loadDrawable()
            await MainActor.run {
                self.drawable = drawable
                let skeleton = drawable.skeleton
                self.allAnimations = drawable.skeletonData.animations.compactMap { $0.name }
                ttprint("allAnimations===> \(self.allAnimations)")
                self.allSkinsName = drawable.skeletonData.skins.compactMap { $0.name }
                ttprint("allSkinsName===> \(self.allSkinsName)")
                
                let spineView = SpineUIView(from: .drawable(drawable),
                                             controller: controller,
                                             mode: .fit,
                                             alignment: .center,
                                             boundsProvider: SetupPoseBounds(),
                                             backgroundColor: .clear)
                self.addSubview(spineView)
                spineView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
                self.applyCostumes()
                self.spineView = spineView
            }
        } catch {
            print("Failed to load skeleton: \(error)")
        }
    }
}

private func applyCostumes() {
    guard let drawable = self.drawable else {
        print("Drawable is not initialized")
        return
    }
    
    customSkin?.dispose()
    
    let skeleton = drawable.skeleton
    customSkin = Skin.create(name: "custom-skin")

    let costumeNames = petModel?.finalSlots ?? []
    ttprint("costumeNames===> \(costumeNames)")
    for costumeName in costumeNames {
        if self.allSkinsName.contains(costumeName), let skin = drawable.skeletonData.findSkin(name: costumeName) {
            customSkin?.addSkin(other: skin)
        } else {
            ttlog.info(event: "⚠️⚠️⚠️未找到该skin", param: ["skin": costumeName, "allSkinsName": allSkinsName.joined(separator: ",")], isAliLog: true)
        }
    }

    skeleton.skin = customSkin
    skeleton.setToSetupPose()
    skeleton.updateWorldTransform(physics: SPINE_PHYSICS_UPDATE)
}

func findSpinePath(fileName: String) -> URL? {
    var atlasUrl = TTAvatarResourceManager.rootPath(giftId: "cat") + "/\(fileName)"
    if FileManager.default.fileExists(atPath: atlasUrl) {
        return URL(string: "file://\(atlasUrl)")
    }
    return nil
}

deinit {
    print("drawable?.dispose()释放了")
    drawable?.dispose()
    customSkin?.dispose()
}

}
如果我把 applyCostumes() 放到 onInitialized后,那么我的视图变得非常大
我应该如何修改???

Related Discussions
...

在您的代码中,applyCostumes() 方法在 onInitialized 回调之后调用时,视图变得非常大。这可能是因为在设置皮肤和更新骨架的过程中,某些变换或设置导致了视图的尺寸不正确。

以下是一些可能的解决方案和建议:

  1. 检查骨架的缩放和变换:确保在设置皮肤后,骨架的缩放和变换是正确的。您可以在 applyCostumes() 方法中添加一些日志来检查 skeleton 的缩放和位置。

  2. 更新视图的布局:在 applyCostumes() 方法中调用 skeleton.setToSetupPose()skeleton.updateWorldTransform() 后,确保更新视图的布局。您可以尝试在 applyCostumes() 方法的末尾调用 spineView.setNeedsLayout()spineView.layoutIfNeeded()

  3. 检查 SpineUIView 的初始化参数:确保 SpineUIView 的初始化参数(如 modealignment)是正确的,以适应您的布局需求。

  4. 调试视图的尺寸:在 applyCostumes() 方法中,添加一些日志来检查 spineView 的尺寸和位置,以确保它们在预期范围内。

  5. 确保皮肤的正确性:在 applyCostumes() 方法中,确保 customSkin 的创建和应用是正确的。检查 costumeNamesallSkinsName 是否包含正确的皮肤名称。

通过这些步骤,您可以更好地调试和解决视图尺寸问题。如果问题仍然存在,您可能需要进一步检查骨架数据和皮肤设置的细节。

  • helloTu hat auf diesen Beitrag geantwortet.

    Spinebot 我都检查过了,这些方案和建议对我没有帮助

    When the SpineView tries to align and fit your skeleton to its bounds, it needs to know the bounds of the skeleton itself. By default, it uses the setup post of the skeleton with the default skin to calculate those bounds, which are then aligned and fitted into the view.

    In your case, I assume the bounds of your setup pose and default skin do not match the bounds when you equip a different skin. Use the boundsProvider parameter to supply the SpineUIView with bounds that cover all your skin variations (use the SkinsAndAnimationBounds class for that, or the RawBounds class if you want to specify the bounds manually). The bounds coordinates and sizes are given in the skeleton's coordinate system as you see it in the Spine Editor.

    See also:
    https://esotericsoftware.com/spine-ios#SpineView-SpineUIView