You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部分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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:39:01