uikit版本demo: gitee.com/past/spine\…
# Spine 动画官网:
#运行时地址:
pod集成:
pod 'Spine', :podspec => 'raw.githubusercontent.com/EsotericSof…'
pod 'SpineCppLite', :podspec => 'raw.githubusercontent.com/EsotericSof…'
pod 'SpineShadersStructs', :podspec => 'raw.githubusercontent.com/EsotericSof…'
注意:
skel格式和json格式都可以。
如果加载出来的效果周边有灰色黑色线条,可以通过修改源码方案解决》Pods/Spine/spine-ios/Sources/Spine/Metal/SpineRenderer.swift
fileprivate extension MTLRenderPipelineColorAttachmentDescriptor {
///修改源码去除黑线
func apply(blendMode: BlendMode, with premultipliedAlpha: Bool) {
isBlendingEnabled = true
sourceRGBBlendFactor = blendMode.sourceRGBBlendFactor(premultipliedAlpha: false)
sourceAlphaBlendFactor = blendMode.sourceAlphaBlendFactor(premultipliedAlpha: true)
destinationRGBBlendFactor = blendMode.destinationRGBBlendFactor
destinationAlphaBlendFactor = blendMode.destinationAlphaBlendFactor
}
}
在限定尺寸的情况下,如需要执行动画,可能有超出视图的情况,方案》
self.spineView = SpineUIView(from: .drawable(drawable),controller: self.spineControl,mode: .fit,alignment: .center,boundsProvider: RawBounds(x: -(self.spineW*2.0), y: -(self.spineH*3.0), width: 844+self.spineW, height: 844+self.spineH))
private var spineAnimationState: AnimationState?
lazy var spineControl: SpineController = {
let controller = SpineController(
onInitialized: { [weak self] controller in
// 设置要播放的动画
controller.animationState.setAnimationByName(
trackIndex: 0,
animationName: "***",
loop: true
)
if let state = controller.animationState as? AnimationState{
self.spineAnimationState = state
}
let skinW = CGFloat(controller.drawable.skeleton.bounds.width / 3.0)
let skinH = CGFloat(controller.drawable.skeleton.bounds.height / 3.0)
let scaleX = self!.spineW / skinW
let scaleY = self!.spineH / skinH
let scale = min(scaleX, scaleY) * 0.7
// 应用缩放
controller.drawable.skeleton.setScale(scaleX: Float(scale), scaleY: Float(scale))
self?.spineView.setNeedsLayout()
}
)
return controller
}()
这里的boundsProvider和controller.drawable.skeleton.setScale是关键。boundsProvider的具体值需要按照自己需求而定
负责做spine文件的同学需要把文件放在坐标0:0上面,否则ios加载出来会有适配问题。
加载完毕后,中途播放别的动画,记得用spineAnimationState播放,避免nil
崩溃容易发生点:
源码里的这个方法func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
需要自行判断下if let wid = size.width as? CGFloat,let hei = size.height as? CGFloat,wid.isNaN == false,wid.isInfinite==false,hei.isNaN == false,hei.isInfinite==false{
线上偶发size计算错误。