在 GameScene 中显示 UIAlertController (SpriteKit/Swift)

Posted

技术标签:

【中文标题】在 GameScene 中显示 UIAlertController (SpriteKit/Swift)【英文标题】:Displaying a UIAlertController in GameScene (SpriteKit/Swift) 【发布时间】:2015-12-19 04:28:59 【问题描述】:

快速显示 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)

这很好,但我使用 SpriteKit 并在 GameScene 中,这给出了一个错误 Value of type 'GameScene' has no member 'presentViewController'...

我是否需要切换回我的 ViewController 来呈现这个,或者有没有办法从 GameScene 中调用它。

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

【问题讨论】:

【参考方案1】:

有很多方法可以处理这种情况,我不建议 Jozemite Apps 回答,因为这会导致具有多个视图控制器的应用程序出现问题。(您希望在当前视图控制器上显示警报,而不是根)

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

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,并让其发送消息;

在视图控制器中

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)

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

在视图控制器代码中: 私有变量 _instance : UIViewController

class ViewController : UIViewController

    class var instance
    
        get
        
            return _instance;
        
    

    func viewDidLoad()
    
       _instance = self;
    

然后调用

ViewController.instance!.  

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

这些方法中的每一种都有优点和缺点,所以选择最适合你的方法。

【讨论】:

哇,很棒的答案。期待尝试这些:D【参考方案2】:

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

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

【讨论】:

不幸的是,这种方法只有在根视图控制器是活动视图控制器时才能正常工作。如果你有多个视图控制器,可能会导致问题。 KnightOfDragon 的回答非常好,突出了一堆点,真的很方便。但是很高兴看到这个小方法,我应该只有 1 个 viewController :) 我不知道它会导致问题,因为我只需要 1 个视图控制器和多个场景。 这个答案的 swift3 版本:self.parent!.scene!.view?.window?.rootViewController?.present(alert, animated: true, completion: nil)【参考方案3】:

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

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

    在您获得的 Podfile 中,复制并粘贴以下内容:pod 'SIAlertView'。它是“用块语法和花哨的转换样式替换 UIAlertView”。 (更多详情here。请注明您正在使用的图书馆作者。

    最后,在您的 GameScene.swift 文件中,在导入后或 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 push”。

上面引用的链接加上this one 帮助我在我的多级游戏中轻松理解和使用这个 UIAlertView,在游戏的“暂停”按钮上显示警报。

【讨论】:

以上是关于在 GameScene 中显示 UIAlertController (SpriteKit/Swift)的主要内容,如果未能解决你的问题,请参考以下文章

无法在 iOS8 上的 UIAlertController 中显示 UIPickerView

Spritekit中的新场景没有显示任何内容?

如何更改启动时显示的默认 SKScene

SKSpriteNode 在 GameScene 中消失

如何在 GameScene 中从 ViewController 调用方法

从 SKSpriteNode 类实例访问 GameScene 中的数组?