Swift和SpriteKit - 如何在GameScene中呈现警告视图

4

我需要帮助在游戏场景中呈现警报视图。由于GameScene.Swift不是标准的ViewController,因此我目前很难做到这一点。如果有帮助的话,我需要这样做是因为我需要用户输入一个值,该值用作我的游戏中球形Sprite Kit节点的坐标。输入只是一个标准整数,所以这不是问题。欢迎任何其他想法,可以不通过警报视图来实现。

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let view = self.view as! SKView

    if view.scene == nil {

        view.showsFPS = false
        view.showsNodeCount = false

        let gameScene = GameScene(size: view.bounds.size)
        gameScene.scaleMode = SKSceneScaleMode.AspectFill
        view.presentScene(gameScene)
    }


}

这在GameViewController文件中

    var vc : GameViewController!



override init(size: CGSize) {
    super.init(size: size)

    let alertController = UIAlertController(title: "Bll Starting Position", message: "Please Enter a X Coordinate Value IN Range 0 to 345 ", preferredStyle: .Alert)
    alertController.addTextFieldWithConfigurationHandler { (textField) in
        textField.placeholder =  "Value Must Be In Range 0 To 345"
        textField.autocapitalizationType = UITextAutocapitalizationType.None
        textField.autocorrectionType = UITextAutocorrectionType.No
        textField.clearsOnBeginEditing = true
        textField.clearsOnInsertion = true
        textField.clearButtonMode = UITextFieldViewMode.Always
        let cancelBtn = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
        let confirmBtn = UIAlertAction(title: "Confirm", style: .Default, handler: { (confirmView) in
            if let field = alertController.textFields![0] as? UITextField {

            }
        })
        alertController.addAction(confirmBtn)
        alertController.addAction(cancelBtn)
        self.vc.presentViewController(alertController, animated: true, completion: nil)

    }

谢谢


检查一下我的答案,可能会有稍微更快的解决方案。 - crashoverride777
2个回答

13

你可以直接在SKScenes中显示UIAlertControllers,只需在rootViewController上显示它们,这可能是显示它们的最佳位置。

view?.window?.rootViewController?.present...

通常情况下,引用GameViewController在SKScenes中不是最佳实践,我从来没有被迫这样做。NSNotificationCenter、委托或协议扩展是更好的方法。

我实际上使用了一个帮助器,该帮助器使用Swift 2的协议扩展来创建警报。

只需创建一个新的.swift文件并添加此代码即可。

import SpriteKit

protocol Alertable { }
extension Alertable where Self: SKScene {

    func showAlert(withTitle title: String, message: String) {

        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

        let okAction = UIAlertAction(title: "OK", style: .cancel) { _ in }
        alertController.addAction(okAction)

        view?.window?.rootViewController?.present(alertController, animated: true)
    }

    func showAlertWithSettings(withTitle 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

            guard let url = URL(string: UIApplicationOpenSettingsURLString) else { return }
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(url)
            } else {
                UIApplication.shared.openURL(url)
            }
        }
        alertController.addAction(settingsAction)

        view?.window?.rootViewController?.present(alertController, animated: true)
    }
}

现在,在您的场景中需要显示警报,只需遵守协议即可。

class GameScene: SKScene, Alertable {

} 

并调用类似的方法

showAlert(withTitle: "Alert title", message: "Alert message")

仿佛它们本身就是场景的一部分。

希望这能帮到你。


语法有点变化,但你的解决方案是 Stack Overflow 上最简单的!谢谢! - tech4242
嘿,谢谢。这是一个较旧的答案,我现在会更新到Swift 3。大部分应该是一样的。 - crashoverride777
已更新至Swift 3。祝编码愉快。 - crashoverride777
谢谢!我已经通过Xcode让它工作了,但这肯定会帮助下一个遇到问题的人 :) - tech4242

4

可能有以下几种选择:

1)快速解决方案。不使用UIAlertController,使用UIAlertView。就像这样:

alert.show()

然而,UIAlertView 已经过时了,所以不能完全依赖它。

2)更好的解决方案是:让你的 SKScene 子类持有对视图控制器的引用,你可以使用该视图控制器来呈现场景,并在创建场景时将其分配给视图控制器:

myScene.viewController = self

然后你就可以使用它了。

self.viewController.presentViewController(alertController, animated: true, completion: nil)

1
它是否看起来像是 "class GameScene : SKScene"? - Andrey Chernukha
1
在GameScene类中写入以下内容:var viewController : UIViewController! - Andrey Chernukha
1
现在,在 view.presentScene(gameScene) 之后,写上 gameScene.viewController = self。 - Andrey Chernukha
1
但是它确实有成员viewController,就像你之前写的那样,对吧?确保GameScene类现在具有属性viewController,并确保将其放置在应该放置的位置。 - Andrey Chernukha
1
你需要做以下事情:1)在真正需要时,在某个点上呈现警报,如果您需要在一开始就显示警报,则可以在 didMove(to:SKView) 方法中执行此操作。2)将 gameScene.viewController = self 放置在 let gameScene = GameScene(size:view.bounds.size) 行的下方。现在它会工作了。 - Andrey Chernukha
显示剩余19条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接