7

I'm making a game in Xcode 8 using SpriteKit and have been having a very difficult time programmatically triggering a segue. I have gone into "Main.storyboard" and made a segue between my "GameViewController" and "MenuViewController" given it the identifier "toMenu".

Failed Attempt #1

Within my GameScene.swift file I have added the following code to the update function.

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    if gameIsRunning == false{
        score = 0
        performSegue(withIdentifier: "toMenu", sender: self)
    }
    }

My goal is for the segue to trigger whenever gameIsRunning is false. However, I got the following error:

Use of unresolved identifier 'performSegue'

This is odd because performSegue is a declaration according to the API Reference.

Failed Attempt #2

I tried this solution by putting the following code into "GameScene.swift"

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    if gameIsRunning == false{
        score = 0
        GameScene(MenuViewController, animated: true, completion: nil)
    }

and I got this error:

Type of expression is ambiguous without more context

Failed Attempt #3

I found this solution very confusing but I following along anyways. I had already done step 1, so as stated in step 2, I put the following code at the bottom of "GameViewController.swift"

func goToDifferentView() {

self.performSegue(withIdentifier: "toMenu", sender: self)

}

and didn't get an error! Then I added this code to "GameViewController.swift" as instructed in step 3 of the solution

    override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "toMenu"), object: nil)

Then I did step 4 of the solution so I put the following code into "MenuViewController.swift"

    override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "toMenu"), object: nil) as Notification)

I then put the following code into my "GameScene.swift" file to actually call the function.

    override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

    if gameIsRunning == false{
        score = 0
        GameViewController().goToDifferentView()
    }

I then ran my game on my iPhone and everything went well until I get to the part of the game where gameIsRunning turns to false. Instead of the segue doing its thing, I got the following error:

Thread 1: Signal SIGABRT

I've gotten this error several times and it's always been that I have something hooked up incorrectly in "Main.storyboard". However, this an incredibly simple game and everything looks normal. I also didn't get this error until adding the code that I just showed you. I have confirmed several times that the segue has the identifier "toMenu". I have absolutely no clue why the segue won't work and why my Attemp #3 is causing a SIGABRT error.

Community
  • 1
  • 1
chas
  • 83
  • 9
  • What kind of segue is it? – GlennRay Apr 03 '17 at 00:46
  • @GlennRay It's kind is 'Show (e.g. Push)' and it is a 'Storyboard Segue'. I'm not sure how to get any additional details about it. – chas Apr 03 '17 at 00:51
  • 1
    Great first question. Tip: if you want to use bold, use double star either side of a piece of text, it's easier to type (and easier to re-edit) than HTML. If you want to format an inline piece of code in a paragraph, `use a backtick` either side. – halfer Apr 03 '17 at 08:43
  • 1
    Shouldn't the post notification statement be in the `if gameIsRunning...` block? – 0x141E Apr 03 '17 at 10:23
  • @0x141E I tried moving the `NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "toMenu"), object: nil) as Notification)' from step 4 of failed solution #3 from the viewDidLoad() in MenuViewController.swift into the 'if gameIsRunning == false' part of the update function in GameScene.sks. I still got a SIGABRT error. – chas Apr 03 '17 at 11:17
  • The `if` and `post` statements shouldn't be in the `update` method. I suggest you move it to where `gameIsRunning` is set to `false` or define a computed property. – 0x141E Apr 03 '17 at 17:56

1 Answers1

2

Since you are trying to trigger this segue in the update() function, it's being called many times per second. Try the following code and it should work.

override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered

if gameIsRunning == false{
    score = 0
    gameIsRunning = true
   NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "toMenu"), object: nil) as Notification)
}

If you were to place print("update") in your if statement you would see what I mean. Setting the gameIsRunning bool to true inside your if will insure it only gets called once.

TheValyreanGroup
  • 3,554
  • 2
  • 12
  • 30