Search code examples
swiftsprite-kitsegue

Segue from SKScene and back again cause game to "freeze"


I'm developing a SpriteKit game with two different scenes (MainMenu.sks and Settings.sks). I also have a UIViewController.

From the MainMenu the user can tap "Settings" which causes the app to load the Settings.sks scene and present it.

It's done using this code:

// Move to Settings.sks
            let transition = SKTransition.flipVertical(withDuration: 1.0)
            let loadScene = SettingsScene(fileNamed: "SettingsScene")
            loadScene?.scaleMode = self.scaleMode
            self.view?.presentScene(loadScene!, transition: transition)

From the Settings.sks scene the user can tap on the SKLabelNode "Change username" which causes the app to load the UIViewController by performing a segue.

The UIViewController contains a UITextField and a UIButton. The UIButton takes the user back to MainMenu.sks.

However, when I'm doing so the it's like a new scene of MainMenu is placed upon the other causing the app to sort of "freeze" and not responding to any touch gestures. I can see from the nodeCount that the nodes are doubled.

A workaround is loading the UIViewController directly from the MainMenu.sks (also via a segue). By doing so, the app works just fine.

I'm suspecting the problem to be the way I load Settings.sks.

What am I missing? Maybe unloading the entire SKView before exiting?


Solution

  • Performing a segue will present a new view on top of the stack. By using a segue to return to the main menu, the app will create a new main menu on top of the UIViewController. I can't say for certain why your app freezes. But I would guess that there are some properties or functions that don't work properly when a new main menu is created and presented from your UIViewController.

    I recommend unwinding the segue used to reach the UIViewController instead. This way you can return to the previous view and conserve memory.

    You'll need to write an IBAction in your destination view, the main menu in this case:

    @IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
    }
    

    Then ctrl-drag from your button in the UIViewController to the exit icon in storyboard. You should see an option to use the IBAction unwindToMainMenu that you just wrote. This will create an unwind segue.

    A complete guide to unwind segues and multiple examples can be found in this answer: What are Unwind segues for and how do you use them?