无法从Spritekit SKScene移植到另一个UIViewController,XCODE8/Swift

问题描述:

我完全停留在试图从我的SpriteKit游戏的第5个和最后一个场景中执行segue到项目中的另一个View Controller(不是GameViewController,也不是根视图控制器)。我尝试从我的finalScene中运行self.view!.window!.rootViewController!.performSegueWithIdentifier(“finalSegue”,sender:self),但它从字面上什么都不做(线被触发,它读取正确的ViewController - 我检查“print(self.view!.window!.rootViewController!)”控制台打印“segue read”,正如我指示的那样,在segue命令之后,作为检查,segue标识符正确,但没有任何反应。无法从Spritekit SKScene移植到另一个UIViewController,XCODE8/Swift

已经尝试调用从GameViewController(我从中启动5个SKScenes视图的视图控制器)执行segue的方法,我得到“意外地发现零,同时展开可选值”。试图从最终的场景(“finalScene.swift”)执行segue,同样的错误。

已经在论坛的其他问题中尝试了所有相关解决方案,以及performSegue方法的“sender:”字段中的nil/self/viewController的所有组合,都无济于事。这里是我试图做的工作,它给出“意外地发现nil,同时展开一个可选的值”,指向viewController var,但是当在设备和模拟器上加载时给出难以理解的调试。它似乎“无”进入viewController var我声明,而不是原始的GameViewController?

我的所有segue标识符在Storyboard中都是正确的,一切都检查了多次...我做错了什么?我应该做一些不同的事情,因为它的第五个SKScene而不是第一个(和其他解决方案一样)?通过从另一个UIViewController进入GameViewController进入SKScenes可以正常工作 - 退出它们不起作用。非常感谢任何帮助,完全卡在这里!

这里是我的相关代码:

在我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 
     } 
    } 
    } 

林我的第五情景,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)    

} 
     } 
    } 

只是为了任何人都可能遇到这个问题,我使用通知中心解决了这个问题。即在游戏场景的父视图控制器上添加了一个通知观察者(它调用一个执行该游戏的函数),并且在我想要执行该游戏的游戏的终点处,我发布了该通知,并且它可以工作大。

中的UIViewController viewDidLoad中添加观察员:

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) 

要调用根的viewController的SEGUE。我认为这是问题。你需要在场景的viewController上调用segue(我假设你已经创建了segue,因此它在根视图控制器上找不到)。

现在的问题是SKScene没有直接访问它的viewController,而只是包含它的视图。您需要手动创建一个指向它的指针。这可以通过创建SKScene属性来完成:

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

然后,在类的viewController,之前skView.presentScene(场景)现在

scene.viewController = self 

,您可以直接访问的viewController。只需在此视图控制器上调用segue:

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

找到此方法也可以正常工作。但我更喜欢上面提到的方法,因为它的线数较少。我真的不知道哪个更适合表演...