【发布时间】:2014-08-28 16:12:54
【问题描述】:
我正在 SpriteKit 中制作一个简单的游戏,并且我正在尝试使用 UIKit 制作一个主菜单。我为主菜单创建了一个视图控制器,并为游戏创建了一个单独的控制器。每当按下播放按钮时,它就会切换到 Game 视图控制器,然后在那里呈现第一个场景。但是,每当它试图将游戏视图控制器的 UIView 投射到和 SKView 以能够呈现场景时,就会失败,并且崩溃报告是汇编,我不知道如何调试。我相信它会实例化游戏视图控制器两次,因为当我在 viewWillLayoutSubviews() 方法中放置一个 println() 时,它会打印两次。另一篇关于此的帖子说该类型在投射期间已经是 SKView ,导致它失败,在这种情况下,这可能意味着当它触发两次时,它会投射一次,然后再次尝试投射并失败。提前致谢!
这里是快速代码
import UIKit
import SpriteKit
class MenuViewController: UIViewController {
let background = UIImageView(image: UIImage(named: "background.png"))
let titleImg = UIImageView(image: UIImage(named: "title.png"))
override func viewDidLoad() {
background.frame = self.view.frame
titleImg.frame = CGRectMake(0, 0, self.view.frame.width, 100)
self.view.addSubview(background)
self.view.addSubview(titleImg)
let bp = ButtonPositions(controller: self)
let play = button(bp.playY, named: "playButton.png")
let leader = button(bp.leaderY, named: "leaderButton.png")
let rate = button(bp.rateY, named: "rateButton.png")
play.addTarget(self, action: "playPressed", forControlEvents: UIControlEvents.TouchDown)
leader.addTarget(self, action: "leaderPressed", forControlEvents: UIControlEvents.TouchDown)
rate.addTarget(self, action: "ratePressed", forControlEvents: UIControlEvents.TouchDown)
self.view.addSubview(rate)
self.view.addSubview(leader)
self.view.addSubview(play)
}
func button(y:CGFloat, named name:String!) -> UIButton {
let bp = ButtonPositions(controller: self)
let img = UIImage(named: name)
let b = UIButton(frame: CGRectMake(bp.x, y, self.view.frame.width / 1.5, img.size.height))
b.setImage(img, forState: UIControlState.Normal)
return b
}
func playPressed() {
println("playPressed") //only prints once
changeVC()
}
func changeVC() {
self.presentViewController(GameViewController(), animated: true, completion: nil) //maybe initializing the GameViewController twice for some reason?
}
func leaderPressed() {
}
func ratePressed() {
}
func center() -> CGPoint {
return CGPoint(x: CGRectGetMidX(self.view.frame), y: CGRectGetMidY(self.view.frame))
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
class GameViewController: UIViewController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
//prepareGame()
println("test") //this prints twice, even through the button press event is only triggered once
}
func prepareGame() {
let skView = self.view as SKView //crashes here when called
let scene = GameScene(size: self.view.bounds.size)
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = true
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> Int {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return Int(UIInterfaceOrientationMask.AllButUpsideDown.toRaw())
} else {
return Int(UIInterfaceOrientationMask.All.toRaw())
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prefersStatusBarHidden() -> Bool {
return false
}
}
【问题讨论】:
-
按定义转换不能失败。但是,您可以转换为错误的类型,这很可能是这里发生的事情。如果您有一个 UIView 并将其转换为 SKView 它不会从中生成一个 SKView,如果您尝试访问 UIView 没有的任何 SKView 属性/方法,它将崩溃。检查 self.view 是否真的是一个 SKView 实例。一个常见的原因是启用 iAd,它出于某种原因将视图控制器的视图替换为它自己的视图。
-
崩溃报告显示堆栈跟踪而不是汇编代码。您所看到的是 Xcode 向您显示崩溃线程的顶部堆栈帧的汇编代码。您应该提供一个完全符号化的崩溃报告(例如,通过在没有调试器的情况下运行应用程序),否则您可能会得到猜测或假设,但仅此而已。
-
哦,好的。谢谢你。我不应该说崩溃报告。当我在没有调试器的情况下运行时,按钮只是冻结在向下位置。当我尝试让 skView = self.view as 时? SKView 和打印出来的,skView 是 nil...
标签: ios xcode swift uikit sprite-kit