在 GameScene 中显示 UIAlertController (SpriteKit/Swift)

Displaying a UIAlertController in GameScene (SpriteKit/Swift)

在 swift 中显示 UIAlertView 的简单方法是:

let alert = UIAlertView()
alert.title = "Alert!"
alert.message = "A wise message"
alert.addButtonWithTitle("Ok, thank you")
alert.show()

但这在 iOS 9 中已贬值,建议使用 UIAlertController:

let myAlert: UIAlertController = UIAlertController(title: "Alert!", message: "Oh! Fancy", preferredStyle: .Alert)
myAlert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(myAlert, animated: true, completion: nil)

这很好,但是我在 GameScene 中使用 SpriteKit,它给出了 Value of type 'GameScene' has no member 'presentViewController'...

的错误

我是否需要切换回我的 ViewController 来展示它,或者有没有办法从 GameScene 调用它。

我找到了 THIS 答案,但它是 Objective-C。

试试这个。我在 SpriteKit 工作,我在我的游戏 Chomp'd 中将此代码用于我的应用内购买消息。

self.view?.window?.rootViewController?.presentViewController(myAlert, animated: true, completion: nil)

有很多方法可以处理这种情况,我不推荐 Jozemite Apps 的答案,因为这会导致具有超过 1 个视图控制器的应用程序出现问题。(你想在当前视图控制器上显示警报,而不是根)

我的首选方式是通过委派。 需要做的是创建一个协议来处理消息传递:

import Foundation
protocol ViewControllerDelegate
{
    func sendMessage(message:String);
}

在您的视图控制器中:

class ViewController : UIViewController, ViewControllerDelegate
{
    ...
    func sendMessage(message:String)
    {
       //do alert view code here
    }

    //in the view controllers view did load event
    func viewDidLoad()
    {
        var view = self.view as! GameSceneView
        view.delegate = self
    }

在您的视图代码中:

  var delegate : ViewControllerDelegate

终于在你要呈现的游戏场景中:

self.view.delegate?.sendMessage(message)

这种方式允许有限地访问 VC,并且可以在需要时使用更多选项进行修改。

另一种方式是设置通知系统,使用NSNotificationCenter将消息从场景传递到当前VC并让它发送消息;

在ViewController

func viewDidLoad()
{
  NSNotificationCenter.defaultCenter().addObserver(self,selector:"AlertMessage:",name:"AlertMessage",object:nil);

}

func AlertMessage(notification:NSNotification)
{
    if(let userInfo = notification.userInfo)
    {
      let message = userInfo["message"]
      ....//do alert view call here
    }
}

在游戏场景代码中:

...at the spot you want to send a message
let userInfo = ["message":message];
NSNotificationCenter.defaultCenter.postNotificationNamed("AlertMessage",object:nil,userInfo:userInfo)

另一种方法是将视图控制器指针保存到游戏场景视图:

//in Game Scene View code
var viewController : UIViewController; 

//in the view controllers view did load event
func viewDidLoad()
{
    var view = self.view as! GameSceneView
    view.viewController = self
}

//finally in game scene where you want to present
let myAlert: UIAlertController = UIAlertController(title: "Alert!", message: "Oh! Fancy", preferredStyle: .Alert)
myAlert.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.view.viewController.presentViewController(myAlert, animated: true, completion: nil)

另一种方法是使您的视图控制器全局化。

在视图控制器代码中: 私有变量_实例:UIViewController

class ViewController : UIViewController
{
    class var instance
    {
        get
        {
            return _instance;
        }
    }

    func viewDidLoad()
    {
       _instance = self;
    }
}

然后打电话给

ViewController.instance!.  

每当您需要访问视图控制器时。

每种方法都有优点和缺点,因此请选择最适合您的方法。

@Knight0fDragon 的回答很好,但我觉得有点长。 我将在这里为新手(其他有同样问题的人)提供另一个使用 Cocoapoad 的 Podfile 的解决方案。

  1. 首先您需要安装 cocoapod 并为您的项目启动它(非常容易做到;查看一些 YouTube 视频或this link

  2. 在您获得的 Podfile 中,复制并粘贴:pod 'SIAlertView'。是"A UIAlertView replacement with block syntax and fancy transition styles"。 (更多详细信息 here。请注明您正在使用的图书馆作者。

  3. 最后,在您的 GameScene.swift 文件中,在导入之后或 class GameScene

    的右括号之后添加以下内容
    private extension GameScene {
        func showPauseAlert() {
            let alertView = SIAlertView(title: "Edess!!", andMessage: "Congratulations! test testing bla bla bla")
    
            alertView.addButtonWithTitle("OK", type: .Default) { (alertView) -> Void in
                print("ok was pushed")
            }
    
            alertView.show()
        }
    }
    

如果需要,您可以添加许多带标题的按钮,并执行任何您想要的操作。这里我只打印 "Ok was pushed".

上面引用的链接加上 this one 帮助我在我的 multiple-level 游戏中理解和使用这个 UIAlertView,在游戏的 "Pause" 按钮上显示警报。