swiftuisprite-kitspriteview

SwiftUI App resets SKScene after becoming active again


Every time my app goes into the background and then becomes active again, SpriteView always resets and the SKScene goes back to the beginning of the level. How can I stop this or what am I doing wrong?

My Code:

struct GameContainer: View {

    private var scene: SKScene {
        let scene = Splash()
        scene.size = Size.shared.setupSceneSize()
        scene.scaleMode = .aspectFit
        return scene
    }  

    var body: some View {
        SpriteView(scene: scene, options: .ignoresSiblingOrder)
            .edgesIgnoringSafeArea(.all)
            .statusBar(hidden: true)
    }
}

struct Game: View {

    ...

    var body: some View {
        NavigationView {
            ZStack {
                GameContainer()
                ....

Update:

struct GameContainer: View {

    static var scene = Splash()

    var body: some View {
        SpriteView(scene: GameContainer.scene, options: .ignoresSiblingOrder)
            .edgesIgnoringSafeArea(.all)
            .statusBar(hidden: true)
    }
}

class Splash: SKScene {
     override init() {
         super.init(size: Size.shared.setupSceneSize())
         scaleMode = .aspectFit
     }
     ....
}

Solution

  • After revisiting this issue and trying different solutions including West1's answer and variations of it, I've come to the conclusion of replacing SpriteView with UIViewRepresentable.

    struct GameContainer: UIViewRepresentable {
    
        func makeUIView(context: Context) -> SKView {
        
            let view = SKView()
            view.ignoresSiblingOrder = true
            view.allowsTransparency = true
        
            let scene = SKScene(fileNamed: "Splash")!
        
            view.presentScene(scene)
        
            return view
        }
    
        func updateUIView(_ uiView: SKView, context: Context) {}
    }
    

    The issue was that SpriteView was updating whenever the player would change color schemes or leave the app. If this happened while mid-game, it can soft lock the player or restart the level.

    UIViewRepresentable doesn't seem to have this issue.

    NOTE: I am using a version of UIViewRepresentable without a coordinator. The coordinator is what is needed to communicate with SwiftUI and the view. I am unsure if it will continuing working if it did have a coordinator.