部分iOS设备上SKScene的didMove(to view: SKView)方法被重复调用两次
iOS 14 环境下 SpriteKit 场景 didMove 方法重复调用修复方案
问题根因
该问题为iOS 14.x版本特有兼容缺陷,iOS 15及以上系统版本已修复SwiftUI视图重绘逻辑中对SpriteKit场景的不必要重复挂载操作。在iOS 14环境中,只要承载GameScene的SwiftUI父视图触发body重绘,已加载的SKScene就会被重复调用didMove(toView: SKView)方法,导致画面被重置为初始状态,但原有场景实例仍在内存中正常运行,因此会出现背景音乐正常播放、后续逻辑回调正常但画面异常的表现。
修复步骤
- 在GameScene类中新增初始化完成标识,拦截重复的挂载逻辑,将原有
didMove(toView: SKView)中的所有初始化代码移动到标识校验之后:
private var isInitialized = false override func didMove(to view: SKView) { super.didMove(to: view) // 拦截第二次及以后的重复调用 guard !isInitialized else { return } isInitialized = true // 原有初始化逻辑:节点添加、参数配置、初始状态设置等全部放在此处 }
- 调整GameScene实例的初始化位置,不要在SwiftUI视图的body属性中直接生成实例,避免每次重绘都生成新的场景对象:
// 正确实现示例 struct GameView: View { private let targetScene: GameScene init() { let scene = GameScene(size: UIScreen.main.bounds.size) scene.scaleMode = .aspectFill self.targetScene = scene } var body: some View { SpriteView(scene: targetScene) // 可选补充:绑定固定ID避免SwiftUI对视图进行不必要的复用重绘 .id("gameSceneUniqueID") } }
内容的提问来源于stack exchange,提问作者Hyoryusha
相关产品推荐
相关产品推荐

