Swift3:在 SKView 中添加 UIAlertController

Posted

技术标签:

【中文标题】Swift3:在 SKView 中添加 UIAlertController【英文标题】:Swift3: adding a UIAlertController in a SKView 【发布时间】:2017-01-24 08:13:39 【问题描述】:

注意:

已经有几个与此相关的问题(或资源):

App Coda: UIAlertController Swift

How would I create a UIAlertView in Swift?

Swift & SpriteKit - How to present alert view in GameScene

Present an UIAlertController with a SpriteKit scene (Objective-C)

Displaying a UIAlertController in GameScene (SpriteKit/Swift)

How to present UIAlertController from SKScene

所以我很抱歉添加了一个类似的问题。但是,我尝试实施这些解决方案但没有成功。

为了使这个问题比上述问题更具体,让我们使用 M.W.E. (Stack Overflow SKSpriteKit) 在另外两个与 Swift 相关的问题中提出:

Swift: SKSpriteKit, using Storyboards, UIViewController and UIButton to set in game parameters? Swift: returning to Main Menu after condition is met in GameScene using StoryBoards and UIViewControllers?

上下文:

在M.W.E. 有一个主UIViewControllerGameViewController 调用主菜单场景,即SKView。各种自定义SKViews循环链接:

菜单 -> 难度 -> 游戏 -> 分数 -> 菜单 -> 等等

我提到这一点,因为在上述大多数问题中,必须将UIAlertController 添加到主UIViewController。我只是想确保只有GameScene 可以呈现UIAlertController 而没有其他场景。

问题:

如何仅从SKViews 之一实现UIAlertController 可调用?之前的一些答案,只有主GameViewControllerGameScene,然后给GameSceneGameViewController中的一个常量)引用GameViewController。由于在此代码中,GameScene 直到很久以后才被访问,如何实现这一点(理想情况下,不通过各种 SKViews 传播对 GameViewController 的引用。

回答此问题时请使用M.W.E.。

目标:

在另一个相关问题中, Swift3: UISwipeGestureRecognizer in only one of putatively many SKViews,它提出了如何为一个SKView 实现UIGestureRecognizer。理想情况下,UIAlertController 将在该操作之后显示 - 作为游戏中的菜单。

最小工作示例

*** SKSpriteKit

【问题讨论】:

我认为之前已经向您指出了这一点,但让我说得很清楚:SpriteKit 和 UIKit 不能很好地配合使用。如果您可以在 SpriteKit 中完成所有操作,那么您将更容易解决这个问题以及所有后续问题。换句话说,您使用故事板和 SpriteKit 的愿望是您最大的问题来源。据我所知,没有人能以这种方式找到快乐的工作方式。 换句话说:SpriteKit 和 GameplayKit 旨在明确地协同工作。这并不有趣,也没有很好的解释或表达,也很少使用。期望两个相互矛盾的框架(SKScene vs UIViewControllers)找到愉快的方式一起玩是在询问很多框架,它们似乎根本没有被设计成要做。他们不是快乐的露营者。 @Confused the M.W.E.不再使用 UIKit 或故事板来处理菜单。如果您有更好的方法来实现弹出暂停菜单,那么我很想向您学习 @SumNeuron 为您在提问方面的进步表示支持,做得好。最小的工作示例是您可以在问题中提出的最好的东西,这很有帮助,太好了。 【参考方案1】:

UIAlert 是一个UIKit 元素,因此您可以轻松地在SKScene 中显示您想要的位置,只需很少的代码即可从您的视图中获取参考。 换句话说,您可以访问显示应用内容的主要window,然后使用提供窗口内容视图的rootViewController

代码示例:

if sprite.contains(touchLocation) 
            print("You tapped the blue sprite")
            let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
            let action = UIAlertAction(title: "Ok", style: .default)  action in
                // Handle when button is clicked
            
            alert.addAction(action)
            if let vc = self.scene?.view?.window?.rootViewController 
               vc.present(alert, animated: true, completion: nil)
            

【讨论】:

【参考方案2】:

似乎是一个很长的问题。你想在 SKScenes 中显示 UIAlertController 吗?无需从您的 SKScene 中引用 GameViewController,只需在根视图控制器上显示警报即可。

所以要直接从您的一个 SKScene 中呈现,您可以这样说

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

希望对你有帮助

【讨论】:

我必须重新创建它们,我只是在尝试我在论坛上能找到的任何东西。这是一个建议......也许你可以在 M.W.E 上演示 MWE 是一个简单的 SpriteKit 项目。例如,要在 GameScene.swift 中显示 UIAlertController ,您通常会创建它,而不是像我的回答那样呈现它。

以上是关于Swift3:在 SKView 中添加 UIAlertController的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3.0:当给定非 SKView 父级时,SKSpriteNode 作为 Button 不起作用?

如何在 SKView 之上添加 UIView?

SKView集成到UIViewController中,UITextFields滞后

以编程方式创建SKView?

Storyboard 在 Xcode9 中找不到 SKView?

带有 Skview 的 ViewController - SpriteKit SKScene