应用挂起 "let SKView as! SKView" (Swift)

App Hanging on "let SKView as! SKView" (Swift)

我正在尝试创建一个基于 SpriteKit 的游戏,并在继续之前尝试建立基本的蓝牙连接,但是我的游戏在从菜单转到 GameScene 时崩溃了,我得到了 "Could not cast value of type 'UIView' to 'SKView'" 错误。我的游戏菜单如下:

import UIKit
import MultipeerConnectivity

class TitleScreenViewController: UIViewController, MCBrowserViewControllerDelegate {


@IBOutlet weak var TitleLabel: UILabel!
@IBOutlet weak var PlayLocallyButton: UIButton!
@IBOutlet weak var PlayOnlineButton: UIButton!
@IBOutlet weak var SettingsButton: UIButton!
@IBOutlet weak var GameCenterButton: UIButton!
var appDelegate:AppDelegate!

override func viewDidLoad() {
    super.viewDidLoad()

    PlayLocallyButton.layer.borderColor = UIColor.blackColor().CGColor
    PlayLocallyButton.layer.cornerRadius = 10
    PlayLocallyButton.layer.borderWidth = 1

    PlayOnlineButton.layer.borderColor = UIColor.blackColor().CGColor
    PlayOnlineButton.layer.cornerRadius = 10
    PlayOnlineButton.layer.borderWidth = 1

    SettingsButton.layer.borderColor = UIColor.blackColor().CGColor
    SettingsButton.layer.cornerRadius = 10
    SettingsButton.layer.borderWidth = 1

    GameCenterButton.layer.borderColor = UIColor.blackColor().CGColor
    GameCenterButton.layer.cornerRadius = 10
    GameCenterButton.layer.borderWidth = 1

    appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.mpcHandler.setupPeerWithDisplayName(UIDevice.currentDevice().name)
    appDelegate.mpcHandler.setupSession()
    appDelegate.mpcHandler.selfAdvertise(true)


}

@IBAction func ConnectWithPlayer(sender: AnyObject) {

    if appDelegate.mpcHandler.session != nil {
        appDelegate.mpcHandler.setupBrowser()
        appDelegate.mpcHandler.browser.delegate = self
        self.presentViewController(appDelegate.mpcHandler.browser, animated: true, completion: nil)


    }

}

func browserViewControllerDidFinish(browserViewController: MCBrowserViewController!) {

    appDelegate.mpcHandler.browser.dismissViewControllerAnimated(true, completion: nil)
    self.performSegueWithIdentifier("OverToGame", sender: self)
}


func browserViewControllerWasCancelled(browserViewController: MCBrowserViewController!) {

    appDelegate.mpcHandler.browser.dismissViewControllerAnimated(true, completion: nil)

}

我的 GameViewController,菜单继续并应该呈现 GameScene,如下所示。这包含它挂起的行

import UIKit
import SpriteKit
import MultipeerConnectivity

extension SKNode {
class func unarchiveFromFile(file : NSString) -> SKNode? {
    if let path = NSBundle.mainBundle().pathForResource(file as String, ofType: "sks") {
        var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
        var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

        archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
        let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene
        archiver.finishDecoding()
        return scene
    } else {
        return nil
    }
  }
}

class GameViewController: UIViewController {

var appDelegate:AppDelegate!

override func viewDidLoad() {

    super.viewDidLoad()

    appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    appDelegate.mpcHandler.setupPeerWithDisplayName(UIDevice.currentDevice().name)
    appDelegate.mpcHandler.setupSession()
    appDelegate.mpcHandler.selfAdvertise(true)

}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let skView = self.view as! SKView

    if skView.scene == nil {

        skView.showsFPS = true
        skView.showsNodeCount = true

        let gameScene = GameScene(size: skView.bounds.size)
        gameScene.scaleMode = SKSceneScaleMode.AspectFill

        skView.presentScene(gameScene)

    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.
}

override func prefersStatusBarHidden() -> Bool {
    return true
  }
}

我是否以正确的方式呈现场景?

您的 class GameViewController 属于 class UIViewControllerUIViewControllerview 属性 属于 class UIView,而不是 SKView.

所以当你写 let skView = self.view as! SKView 你是在说,嘿,我确定我的 self.view 应该是 SKView 类型,如 [=19] 所示=].但事实并非如此,幸运的是编译器在你 运行 你的应用程序崩溃之前阻止了你。

SKViewSKScene

view 属性 的 class

要使用 Sprite Kit 编写游戏,您必须了解 UIViewControllerSKScene 之间的区别,祝您好运!

SKScene class reference

UIViewController class reference