簡體   English   中英

無法從Spritekit SKScene轉到另一個UIViewController,XCODE8 / Swift

[英]Unable to segue from Spritekit SKScene to another UIViewController, XCODE8/Swift

我完全堅持嘗試從我的SpriteKit游戲的第5個和最后一個場景中執行一個segue到項目中的另一個View Controller(不是GameViewController,也不是根視圖控制器)。

我嘗試運行self.view!.window!.rootViewController!.performSegueWithIdentifier(“finalSegue”,sender:self),來自我的finalScene,但它確實什么都沒做(行被觸發,它讀取正確的ViewController - 我檢查“打印(self.view!.window!.rootViewController!)“控制台打印”segue讀取“按照我的指示,在segue命令之后,作為檢查,segue標識符是正確的,但沒有任何反應)。

嘗試調用一個從GameViewController(我正在啟動5個SKScenes視圖的視圖控制器)執行segue的方法,我得到“在展開可選值時意外發現nil”。 嘗試從最終場景(“finalScene.swift”)執行segue,同樣的錯誤。

已經在論壇中的其他問題中嘗試了所有相關解決方案,以及performSegue方法的“sender:”字段中的nil / self / viewController的所有組合,但無濟於事。 這是我正在努力做的工作的代碼,它給出了“在展開可選值時意外發現nil”,指向viewController var,但在設備和模擬器上加載時給出了難以理解的調試。 似乎“nil”傳入我聲明的viewController var,而不是原來的GameViewController?

我在Storyboard中的所有segue標識符都是正確的,所有內容都經過多次檢查...我做錯了什么? 我應該做一些不同的事情,鑒於它的第5個SKScene而不是第1個(與其他解決方案一樣)? 通過從另一個UIViewController中進入GameViewController而進入SKScenes的工作正常 - 它們退出它們不起作用。 非常感謝任何幫助,完全卡在這里!

這是我的相關代碼:

在我的GameViewController(啟動我的5個連續SKScenes的UIViewController)中:

    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)            

}
        }
    }

對於任何可能遇到此問題的人,我都是通過使用通知中心解決的。 即在游戲場景的父視圖控制器上添加了一個通知觀察者(調用執行segue的函數),並且在我想要做segue的游戲的終點,我發布了該通知,它的工作原理大。

在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,因此它沒有在根viewController上找到)。

現在問題是SKScene沒有直接訪問它的viewController,而只是它包含它的視圖。 您需要手動創建指向它的指針。 這可以通過為SKScene創建屬性來完成:

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

然后,在viewController類中,就在skView.presentScene(scene)之前

scene.viewController = self

現在,您可以直接訪問viewController。 只需在此viewController上調用segue:

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

發現這種方法同樣適用。 但我確實更喜歡上面提到的方法,因為它的線數較少。 我不知道哪個更適合表現......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM