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

如何使用SwiftUI的SpriteView(isPaused:)暂停SKScene且不重复初始化

问题根因

场景反复重建的核心原因并非isPaused参数使用错误,而是当前代码中scene为计算属性,每次SwiftUI因showingLevelChooser状态变化重绘视图时,都会重新生成全新的GameScene实例,导致计时器清零。

解决方案

使用@State修饰符持有GameScene实例,保证它在视图生命周期内仅初始化一次即可,修改后的ContentView代码如下:

struct ContentView: View {
    @State private var showingLevelChooser = false
    // @State持有场景实例,仅初始化一次
    @State private var scene: GameScene = {
        let scene = GameScene()
        scene.size = CGSize(width: 300, height: 400)
        scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        scene.scaleMode = .fill
        return scene
    }()
    
    var body: some View {
        ZStack {
            SpriteView(scene: scene, isPaused: showingLevelChooser)
                .ignoresSafeArea()
            VStack {
                Button("Level Chooser") {
                    showingLevelChooser.toggle()
                }
                Spacer()
            }
        }
        .sheet(isPresented: $showingLevelChooser) {
            VStack {
                Button("Cancel") {
                    showingLevelChooser.toggle()
                }
                Text("Level Chooser")
            }
        }
    }
}

原理解释

@State修饰的引用类型会在SwiftUI的视图生命周期中保持同一个实例,不会随body重绘反复生成。此时传入isPaused参数,SwiftUI只会更新SpriteView的暂停状态,不会触发场景重建,游戏计时会在弹窗关闭后继续累计。
如果场景需要在多视图间共享,也可以将其放到符合ObservableObject协议的视图模型中,通过@StateObject持有视图模型即可。

内容的提问来源于stack exchange,提问作者clns

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:45:05