如何在GameScene中从ViewController中调用方法

我有一个方法,在我的viewController中有一个自定义的segue,看起来像这样:

func gameOver() { performSegueWithIdentifier("GameOver", sender: nil) } 

我在GameScene.swift中调用方法如下:

  GameViewController().gameOver() 

我仔细检查了赛格的名字,这是正确的。 每当我在我的GameScene.swift文件中调用此函数,我都会收到SIGABRT消息,我不知道为什么。 我试着只用println()消息调用函数,它工作。

任何意见,为什么发生这种情况,以及如何成功地调用GameScene.swift文件中的方法将不胜感激。

谢谢!

PS这里是崩溃日志:

 2015-01-28 21:59:46.181 RunawaySquare[95616:3907041] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<RunawaySquare.GameViewController: 0x7fe4305c7890>) has no segue with identifier 'GameEnd'' *** First throw call stack: ( 0 CoreFoundation 0x000000010d461f35 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010f39ebb7 objc_exception_throw + 45 2 UIKit 0x000000010e20dd3b -[UIViewController shouldPerformSegueWithIdentifier:sender:] + 0 3 RunawaySquare 0x000000010d2683b2 _TFC13RunawaySquare18GameViewController8gameOverfS0_FT_T_ + 914 4 RunawaySquare 0x000000010d261af0 _TFC13RunawaySquare9GameScene12touchesBeganfS0_FTCSo5NSSet9withEventCSo7UIEvent_T_ + 1808 5 RunawaySquare 0x000000010d261c3f _TToFC13RunawaySquare9GameScene12touchesBeganfS0_FTCSo5NSSet9withEventCSo7UIEvent_T_ + 79 6 SpriteKit 0x000000010df4d7e1 -[SKView touchesBegan:withEvent:] + 946 7 UIKit 0x000000010e12d16e -[UIWindow _sendTouchesForEvent:] + 325 8 UIKit 0x000000010e12dc33 -[UIWindow sendEvent:] + 683 9 UIKit 0x000000010e0fa9b1 -[UIApplication sendEvent:] + 246 10 UIKit 0x000000010e107a7d _UIApplicationHandleEventFromQueueEvent + 17370 11 UIKit 0x000000010e0e3103 _UIApplicationHandleEventQueue + 1961 12 CoreFoundation 0x000000010d397551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 13 CoreFoundation 0x000000010d38d41d __CFRunLoopDoSources0 + 269 14 CoreFoundation 0x000000010d38ca54 __CFRunLoopRun + 868 15 CoreFoundation 0x000000010d38c486 CFRunLoopRunSpecific + 470 16 GraphicsServices 0x000000011480e9f0 GSEventRunModal + 161 17 UIKit 0x000000010e0e6420 UIApplicationMain + 1282 18 RunawaySquare 0x000000010d26cbee top_level_code + 78 19 RunawaySquare 0x000000010d26cc2a main + 42 20 libdyld.dylib 0x000000010fb8a145 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException 

它说没有segue id。 与“GameEnd”,但有一个,它的作品,如果在视图控制器上使用

这不工作的原因是你正在创build一个gameOver的新实例,然后你打电话给gameOver 。 你真正想做的是参考你现有的GameViewController

有几种方法可以做到这一点,我会给你一个例子。

添加一个viewController属性到你的GameScene类

 class GameScene { // we need to make sure to set this when we create our GameScene var viewController: GameViewController! 

在你的GameViewController文件中

 // after GameScene is instantiated gameScene.viewController = self 

现在我们有一个对viewController的引用,可以在我们的GameScene类中使用它

 // somewhere in GameScene self.viewController.gameOver() 

我通过创build协议完成,我有3个游戏场景(GameScene,GamePlayScene,GameEndScene)和一个游戏控制器(GameViewController)

首先创buildgameProtocol

 protocol GameDelegate { func gameOver() } 

在GameViewController中实现协议

 class GameViewController: UIViewController, GameDelegate { override func viewDidLoad() { super.viewDidLoad() let scene = GameScene(size: skView.bounds.size) scene.scaleMode = .AspectFill scene.delegate = self } // MARK: Game Delegate func gameOver() { self.performSegueWithIdentifier("yoursegue", sender: self) } } 

在GameScene类中放置委托属性

 class GameScene: SKScene { var delegate: GameDelegate? // call GamePlayScene and put delegate property func redirectToPlay() { let transition = SKTransition.pushWithDirection(SKTransitionDirection.Left, duration: 1.0) let menuScene = GamePlayScene(size: size) menuScene.delegate = self.delegate self.view?.presentScene(menuScene, transition: transition) } } 

并把协议放在GamePlayScene中

 class GamePlayScene: SKScene { var delegate: GameDelegate? // call GameEndScene and put delegate property func gameScore() { let transition = SKTransition.pushWithDirection(SKTransitionDirection.Left, duration: 1.0) let menuScene = GameEndScene(size: size) menuScene.delegate = self.delegate self.view?.presentScene(menuScene, transition: transition) } } 

最后放置委托属性并调用gameOver函数

 class GameEndScene: SKScene { var delegate: GameDelegate? init(size: CGSize) { // call gameOver function self.delegate?.gameOver() } } 

希望工作,可以帮助你

真诚的唐尼

我不知道这是否仍然相关,但我想为您解决这个问题。

正如你可以在这里看到的Swift iOS:从一个ViewController中的实例执行Segue到另一个ViewController前一段时间我有完全相同的问题,我设法使用协议来修复。

问题是,你只能在你的GameViewController类中调用“performSegueWithIdentifier(”GameOver“,sender:nil)”,但是你想从你的Gamescene中执行它。

因此,你在GameScene中创build一个这样的协议:

 @objc protocol GameOverDelegate { func gameOverDelegateFunc() } 

以及Gamescene中委托的variables:

 var gamescene_delegate : GameOverDelegate? 

在您的GameViewController类中,您必须在类定义中添加委托

 class GameViewController: UIViewController, GameOverDelegate { ... } 

并在GameViewController的viewDidLoad函数中将场景的委托设置为self:

 scene.gamescene_delegate = self 

最后一步是在GameViewController中实现gameOverDelegateFunc()函数:

 func gameOverDelegateFunc() { self.performSegueWithIdentifier("GameOver", sender: nil) } 

这是你所要做的。

每当你想在你的GameScene中执行这个Segue时,你只需要通过代理调用这个函数就可以了:

 gamescene_delegate?.gameOverDelegateFunc() 

我希望一切都清楚,我可以帮忙,

问候,菲尔

我没有足够的代表来回复你的最后一条评论,但是如果你仍然得到这个错误,那是因为你还没有在界面生成器中给出这个名字(或标识符)。

当您单击并拖动以在界面构build器中的视图控制器之间绘制轮廓时,可以通过在轮廓线中央出现的圆形图标来select每个转换,并给它一个“标识符”。 那么,当你调用performSegueWithIdentifier ,它应该工作!

这是圆形图标的样子,取决于segue的types:

Segue图标,让您管理赛格属性

如果你对赛季有些不确定,请查看本教程或这个 教程 !