Swift SpriteKit:在GameScene中访问UIViewController的最佳实践
我想看看从GameScene访问UIViewController方法的最佳做法是什么。 现在我一直在使用NSNotificationCenter,但是我不想使用这个,因为我想要实现的特定function。
此外,如果没有任何其他方式通过GameScene获得对UIViewController的访问,那么我真正想知道的是一种能够在没有UIViewController的情况下在GameScene中呈现UIAlertController的方法。
我只是创build一个全局variables的UIViewController,但我听说这是不好的做法。
谢谢!
您可以在SKScenes中显示UIAlertControllers,只需将它们显示在rootViewController上,这可能是最好的显示它们的地方。
self.view?.window?.rootViewController?.present...
我不喜欢在SKScenes中引用GameViewController,而且我从来没有真正到过一个我被迫这样做的地步。 NSNotificationCenter,委托或协议扩展是更好的方法。
实际上,我使用Swift 2的协议扩展提供的帮助,因为我喜欢干净,可重用,尽可能less的重复代码。
只需创build一个新的.swift文件并添加此代码
import SpriteKit protocol Alerts { } extension Alerts where Self: SKScene { func showAlert(title title: String, message: String) { let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) let okAction = UIAlertAction(title: "OK", style: .Cancel) { _ in } alertController.addAction(okAction) self.view?.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil) } func showAlertWithSettings(title title: String, message: String) { let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) let okAction = UIAlertAction(title: "OK", style: .Cancel) { _ in } alertController.addAction(okAction) let settingsAction = UIAlertAction(title: "Settings", style: .Default) { _ in if let url = NSURL(string: UIApplicationOpenSettingsURLString) { UIApplication.sharedApplication().openURL(url) } } alertController.addAction(settingsAction) self.view?.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil) } }
现在在你的场景中,你需要显示警报,你只需要遵守协议
class GameScene: SKScene, Alerts { }
并调用方法
showAlert(title: "Alert title", message: "Alert message")
就好像它们是场景本身的一部分一样。
请享用
这有点不好意思,但直接从视图控制器访问函数使用这个:
(view?.nextResponder() as? MyViewController)?.presentAlert()
这依赖于你的SKView是视图控制器中的主视图。 如果不是,那么你需要添加.superview?
你view?
呼叫。
我发布的前一个答案(以及更合适的方法)的替代方法是在场景类中创build一个属性,以存储对视图控制器的引用,并使用它:
class MyGameScene: SKScene { weak var viewController: MyViewController? func somethingHappened() { viewController?.presentAlert() } }
当你在你的控制器中呈现这个场景时,一定要设置一个对你的视图控制器的引用:
if let scene = GameScene(fileNamed:"GameScene") { scene.viewController = self // other stuff skView.presentScene(scene) }