Using manuel segues with Swift Spritekit - swift

(Swift) I have a problem with my app, I'm working on. It features a SpriteKit Scene and some transitions to different scenes. However, from the main menu of the app, I've created a segue to a new viewController via Story Board.
My problem is, when I - in my sprite kit scenes, browse back to the main menu to trigger the Story Board scene my app crashes.
I can only use the Story Board segue if restart my App and triggers it from the main menu as the first thing.
Also, when I get back to my Sprite Kit Scene from the new viewController, I cannot use any of the nodes (as buttons) to make transitions to other sprite kit scenes.
I've tried to illustrate it here:
Code for calling the segue:
func goto_achievements() {
self.viewController?.performSegueWithIdentifier("achievements", sender: self)
}
Any help appreciated!

Related

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?
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?

Go to Gamescene back to viewcontroller

I have a simple game. there are two Viewcontroller. after pressing "play" on the first viewcontroller i have performed a segue to the secondviewcontroller. this secondviewcontroller contains a GADBannerView and a button to stop the game and presents a Gamescene. if the user loses it shows up a new game scene. if the user clicks on the GameoverScene the game restarts. I would like to to perform a segue after the user press on the button and i would like to go back to the first Viewcontroller. I've made it in the storyboard. the problem is that the game doesn't stop. (i know it because i have a background music) and once i'm in the first viewcontroller if I click again "play" the game doesn't work as it should. i've figured that the problem occurs when i click the "back button". how can I dismiss the game scene and go back to the first viewcontroller?
There's no way to tell what your problem is, because you didn't post any code, but you can try something like this to dismiss your Game Scene:
self.view?.presentScene(nil) // From your Game Scene!
I have a game, and I use a method that does that job, and it looks something like this:
class GameScene : SKScene {
// ...
func dismiss() {
self.removeAllActions()
self.removeAllChildren()
self.removeFromParent()
self.view?.presentScene(nil)
}
// ...
}
After that, call the method that will present your ViewController!
Hopefully that's useful for you!

Swift - Deallocate previous view controller after segue

I'm trying to find a proper way to handle my scene/view process flow in my game. I'm currently able to transition from a main menu to a game level, exit the game level and return to the main menu, but it's not deallocating any of the memory from any of the views.
I saw a lot of suggestions to use a UINavigationController to handle my view controllers. After trying that for a while, my current storyboard looks like this:
My root view controller is Menu View Controller. I first start in Title View Controller, segue to Menu View Controller, then segue to and from Game View Controller, but this is obviously not deallocating any of my memory.
My segues are done from within SKScenes using the following:
self.viewController?.performSegueWithIdentifier("segueName", sender: viewController)
where viewController is a var within the SKScene referencing its parent view controller.
Is there something I could try to get my process flow to work out? I just want to be able to traverse a title scene for login and server connections, then spend the rest of the time switching between a menu scene and some sort of game scene.
I've tried to implement a few suggestions, for example, dismissViewControllerAnimated(true, completion: nil) but none of them seem to be actually deallocating anything. The game slows to a crawl after just 2-3 cycles between the menu scene and game scene.
I've seen quite a few questions similar to this, but I've been so far unable to come up with a solution that works for me. I'm writing a game in Swift and Xcode 7.3.1.
I solved my issue. I ended up having a bunch of strong references to various things like my view, scene, and view controller. I had ~200 strong references in total, so I have a lot of cleaning up to do.
To find my strong references, I followed a guide on how to use Allocation Instruments in Xcode here: https://www.raywenderlich.com/97886/instruments-tutorial-with-swift-getting-started
Anyone with this same issue, check out this question: In swift, how to get memory back to normal after an SKScene is removed?
That's what helped me fix my issue.
So you've looked at a number of different approaches but most aren't appropriate for you and / or have been applied incorrectly.
You now have an unused navigation controller in your app. In general I would use a navigate controller, but it should be marked as the initial view controller and your current initial view controller should be the nav controllers root view controller.
Once you have that, you need to look into unwinding segues (or use a little code). At the moment you're just always showing new view controller instances, you're never going back. This is why you start having issues. You need to unwind from the game scene to the menu instead of showing a new menu.
That can also be done with code by telling the nav controller to pop the top view controller off its stack.

Using SpriteKit in AppKit app swift

I'm writing some games for Mac OS (using AppKit with storyboards and without core data) and my project is quite big, so rewriting it using SpriteKit will be very difficult and long process. So, is there any way to add a game written on SpriteKit to this project?
This is exactly what the SpriteKit Game template you can start a new app with in Xcode is. There's nothing magic about it — it's an AppKit app, containing an SKView that displays an SKScene.
Take a look at a new project created with that template to see how it works. Create an SKView in code or in IB, make an outlet to it, and from your app's controller code (say, in the app delegate or a window controller), create a scene and pass that to the view's presentScene method.

How do I use storyboards with spriteKit using swift

One of my main reason for using Xcode instead of other applications for making iOS apps was the storyboard interface builder. I was unhappy when I found out that you are not meant to use storyboards with spriteKit. I find it hard to design a nice interface for a game's menu without a good visual builder. Is there a way to start a spriteKit application using storyboards, then with a click of a "start game" button, switch to spriteKit scenes, then when you lose the game, in the code switch back to storyboards(using swift)? Please help and thanks.
-Callum-
A SpriteKit Scene is presented on an instance of a SKView, which is a subclassed UIView.
For an iOS game made using SpriteKit, one needs to have at least one viewController set up, either programatically in the App delegate or in a storyboard, on which the SKScene can be displayed. It is on the main view of this VC that a SKScene will be presented in.
So if you are using a storyboard, the iOS game will have to instantiate the root viewController from it. You can easily design your UI on the viewController, and present the game from the code on the press of a button, either in the same viewController or a new one. All this will be evident once you read a beginner tutorial for SpriteKit using Swift like this.
Let's say your root viewController has your main menu (on another view called menuView), with a play button on it. Now presenting a game on the press of a button would look something like this:
class MyViewController: UIViewController {
#IBOutlet wear var menuView: UIView?
#IBOutlet weak var playButton: UIButton?
#IBAction func likedThis(sender: UIButton) {
//Hide the menu view
menuView.hidden = true
//instantiate and present the scene on the main view
let scene = MyScene(size: view.bounds.size)
let skView = self.view as SKView
skView.presentScene(scene)
}
}
As for going back to the main menu from the scene, have a look at this answer.