再谈 SCNNode 贴图类型选择问题

535 阅读2分钟

存在的问题

上次写到《SCNNode到底应该怎么贴图?UIImage,UIImageView,CALayer用哪个?》列举了贴图的使用。但是,实际使用中发现,不同的贴图其实有不同的问题。

Image/Texture

这些贴图实际就是图片,整体支持较好,但是当我们需要复杂内容布局时,只能是都转化为图片。

UIView

官方不推荐直接使用 UIView,但是仍然是可以使用的。

  • 优点:支持复杂布局和图文视频混排(Autolayout/Frame),支持滚动动画,支持触摸手势。
  • 缺点:内存泄露,手势响应永远最高级,不支持 CALayer/UIView 动画。Frame 不是整数时可能会崩溃,偶发布局错乱。每贴图一个 UIView,视图层级上就会多出一个_SCNSnapshotWindow层,可能会造成其它界面的手势/键盘失效。

CALayer

官方推荐使用,可支持动画。

  • 优点:支持复杂布局和图文视频混排,sublayer 支持 CAAnimation 动画。支持 SCNView 的 prepareObjects:withCompletionHandler:方法,后台传输到 GPU,避免带宽卡顿。
  • 缺点:坐标和布局与 UIView 不同,且不支持 Autolayout,不支持触摸手势,后台线程创建 layer 再切换主线程显示,仍可能会显示不出来。

SpriteKit

官方推荐使用,可支持动画。

  • 优点:支持复杂布局和图文视频混排,支持动画,原生支持纹理组预加载到内存,支持二维灯光/物理效果/粒子效果,支持 SKConstraint 和 SKAction。
  • 缺点:坐标和布局与 UIView 不同,且不支持 Autolayout,不支持触摸手势(本身是支持的,但在 AR 中无法使用),不支持 SCNView 的 prepareObjects:withCompletionHandler:方法。 贴图上下颠倒了,需要反转。

最后的选择

经过实践中的对比,综合各方面对比:类型支持,内容创建,性能优化,显示效果等,得出下面结论:

  • 如果是静态的内容展示,还是用 Image/Texture 最为方便,少资源占用,复杂布局可以用 UIView 完成后画出来,保存为图像,再贴图;
  • 动画内容可选 CALayer 和 SpriteKit, 一般 CALayer 更熟悉更容易上手;
  • SpriteKit 目前实践中来说,虽然功能更强大一些,但优势不够明显:需要一定学习成本,布局方式和 UIView/CALayer 都不太一样,另外有潜在的性能问题(调试工具中有警告大意说“不要在运行时修改 GPU 上的内容”)