2016-11-28 2 views
1

Я полностью застрял в попытке выполнить segue из 5-й и последней сцены моей игры SpriteKit другому Контроллеру просмотра в проекте (не GameViewController, ни контроллер корневого представления).Невозможно перейти от Spritekit SKScene к другому UIViewController, XCODE8/Swift

Я попытался запустить self.view !.window! .rootViewController! .performSegueWithIdentifier («finalSegue», отправитель: self), из моего finalScene, но он буквально ничего не делает (строка запускается, она читает правый ViewController - я проверяю «print (self.view! .window! .rootViewController!)». Консоль печатает «segue read», как я проинструктировал его, сразу после команды segue, в качестве проверки, идентификатор segue верен, но ничего не происходит).

Пробовал вызывать метод, выполняющий segue из GameViewController (контроллер вида, из которого я запускаю представление 5 SKScenes), я получаю «неожиданно найденный nil при распаковке необязательного значения». Пробовал выполнить сеанс из финальной сцены («finalScene.swift»), ту же ошибку.

Пробовал все и все релевантные решения в других вопросах на форуме, а также все комбинации nil/self/viewController в поле «отправитель:» метода performSegue, но безуспешно. Вот код, который я пытаюсь сделать, чтобы «неожиданно найти нуль при распаковке необязательного значения», указывая на viewController var, но предоставляя непонятную отладку при загрузке как на устройстве, так и на симуляторе. Кажется, «nil» переходит в viewController var, который я объявляю вместо исходного GameViewController?

Все мои идентификаторы segue верны в раскадровке, все проверено несколько раз ... Что я делаю неправильно? Должен ли я делать что-то другое, учитывая его 5-й SKScene, а не 1-й (как в других решениях)? Segue в SKScenes, перейдя в GameViewController из другого UIViewController, отлично работает - его выход из них не работает. Большое спасибо за любую помощь, полностью застрявшую здесь!

Вот мой соответствующий код:

В моей GameViewController (UIViewController, который запускает свои 5 последовательных SKScenes):

class GameViewController: UIViewController { 
     let myScene = finalScene() 
     override func viewDidLoad() { 
      super.viewDidLoad() 

    if let view = self.view as! SKView? { 

//this is the 1st out of 5 SKScenes in the project 
       let scene = GameScene(size: CGSize(width: 2048, height: 2742)) 

//this is the 5th out of 5 scenes, that I am trying to trigger the segue out of 
       myScene.viewController = self 
       view.presentScene(scene) 
       view.ignoresSiblingOrder = true 
     } 
    } 
    } 

Im моя пятая сцена, finalScene:

class finalScene: SKScene { 

    var viewController: GameViewController! 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

     for touch: AnyObject in touches{ 

      let positionOfTouch = touch.location(in: self) 
      let tappedNode = atPoint(positionOfTouch) 
      let nameOfTappedNode = tappedNode.name 
      if nameOfTappedNode == "continue" { 

self.viewController.performSegue(withIdentifier: "finalSegue", sender: self)    

} 
     } 
    } 

ответ

0

Только для любой, кто может столкнуться с этим, я решил это, используя центр уведомлений. Т.е. добавил наблюдателя уведомления на родительском контроллере представлений игровых сцен (который вызывает функцию, выполняющую segue), а в конечной точке игры, где я хотел выполнить сеанс, я отправил это уведомление, и он работает Великий.

добавление наблюдателя в ViewDidLoad от UIViewController:

override func viewDidLoad() { 
     super.viewDidLoad() 

      NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.doaSegue), name: NSNotification.Name(rawValue: "doaSegue"), object: nil) 
} 

    func doaSegue(){ 
     performSegue(withIdentifier: "toNext", sender: self) 
     self.view.removeFromSuperview() 
     self.view = nil 
    } 

И затем вызвать его из игры SKScene:

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "doaSegue"), object: nil) 
0

Вы вызываете SEGUE на корневом ViewController. Я думаю, что это проблема. Вы должны вызвать segue на viewController сцены вместо этого (где я предполагаю, что вы создали segue, следовательно, он не находится на корневом viewController).

Теперь проблема заключается в том, что SKScene не имеет прямого доступа к его viewController, а просто к виду, в котором он содержится. Вам нужно создать указатель на него вручную.Это может быть сделано путем создания свойства для SKScene:

class GameScene: SKScene { 
    var viewController: UIViewController? 
    ... 
} 

Тогда в классе ViewController, как раз перед skView.presentScene (сцена)

scene.viewController = self 

Теперь вы можете получить доступ к ViewController непосредственно. Просто вызовите SEGUE на этом ViewController:

func returnToMainMenu(){ 
    self.viewController.performSegueWithIdentifier("menu", sender: vc) 
} 

Найдено этот метод работать так же хорошо. Но я предпочитаю метод, упомянутый выше, так как он меньше строк. Я действительно удивляюсь, что лучше для производительности ...

Смежные вопросы