【问题标题】:How can I dismiss a ViewController from my GameScene.swift?如何从我的 GameScene.swift 中关闭 ViewController?
【发布时间】:2016-05-21 18:42:55
【问题描述】:

问题:如何从我的 GameScene.swift 中关闭 ViewController?


情况:我的 SpriteKit 游戏中有 2 个 VC,如下所示:

ViewController.swift ----Press Play-----> GameViewController

当玩家失败时,我想关闭 GameViewController 以便玩家可以再次按下播放键。我在我的 GameScene.swift 中检查玩家的损失,并希望从那里关闭 GameVC。


注意: 谷歌搜索没有成功。


我尝试了什么:

1) 在我的 GameScene.swift 中创建一个 gameVC 实例并像这样关闭它:

let gameVC = GameViewController()
gameVC.dismissViewController(false,completion: nil)

2) 做:

self.view.window!.rootViewController?.dismissViewControllerAnimated(false, completion: nil)

那些不工作的原因很明显^^

【问题讨论】:

  • 1) 不起作用:您需要使用 existing 实例,而不是新实例。 2) 仅当 self.view.window!.rootViewController? 是您的 GameViewController 实例时才有效,但看起来这可能是 ViewController
  • @AaronBrager 是的,我知道 :) 这就是为什么我把它放在“我试过的”部分的原因。我只是看不到如何获取现有实例:/
  • 您需要向GameScene 提供对视图控制器的引用,以便它可以将其关闭,或者使用委托模式与控制对象进行反向通信,VC 应该自行关闭/关闭
  • @AaronBrager 将此作为答案,以便我接受(如果可行):D

标签: ios swift uiviewcontroller sprite-kit


【解决方案1】:

您不想“抓取”现有实例:https://pragprog.com/articles/tell-dont-ask

您需要向 GameScene 提交对视图控制器的引用,以便它可以将其关闭,或者使用委托模式与控制对象进行反向通信,VC 应该自行关闭/关闭。

一个简单的例子……你可以给GameScene添加一个GameViewController属性,然后在适当的时候关闭VC:

class GameScene: SKScene {
    var gameVC: GameViewController?

    func gameDidEnd() {
        gameVC?.dismissViewControllerAnimated(true) {
            // if desired, do any cleanup after the VC is dismissed
        }
    }
}

那么,首先在创建GameScene对象时设置这个属性:

if let gameScene = GameScene(fileNamed: "MyScene") {
    gameScene.gameVC = someGameVC
}

这种简单的方法将紧密结合GameSceneGameViewController,如果您想使用其中一个对象而不使用另一个对象,则变得更加困难。但是对于这个简单的用例,它可能没问题。

【讨论】:

  • 感谢您的回答,但 SO 反对仅链接的答案,因为它们可能会变得无效。您能否添加一个代码 sn-p 以便我接受您的答案并投票? :)
  • 当然,我很高兴。一秒
  • 我在尝试这个之后现在有内存泄漏:/
  • 你能详细说明吗?
  • 每次我输了(关闭 GameVC,因此回到有播放按钮的 mainVC)再玩一次,FPS 下降。
【解决方案2】:

我关注了你的一些讨论。我想添加一些代码,因为通常我更喜欢使用一个或两个 ViewController 以及许多 SKScene 和 SKNode,但在这种情况下,有一个 currentViewController 参考可能很有用:

class MyModelScene: SKScene {
   let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
   var currentViewController : MyModelViewController! = MyModelViewController() 
 // MyModelViewController is a customized UIViewController

   override func didMoveToView(view: SKView) {
      super.didMoveToView(view)
      print("---")
      print("∙ \(NSStringFromClass(self.dynamicType))")
      print("---")
   }
}

class Level1Scene: MyModelScene {
    ...
}

UIViewController

class PreloadViewController: MyModelViewController {
     override func viewDidLoad() {
        super.viewDidLoad()

        if let scene = Level1Scene(fileNamed:"Level1Scene") {
            // Configure the view.
            let skView = self.view as! SKView
            skView.showsFPS = true
            skView.showsPhysics = true
            skView.showsNodeCount = true

            skView.ignoresSiblingOrder = true

            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .ResizeFill 
            scene.currentViewController = self
            skView.presentScene(scene)
        }
    }
}

使用此代码,您的SKScene 中始终有一个 currentViewController 引用,您可以检查它是否是您想要关闭的正确 viewController。

【讨论】:

  • 你不需要NSStringFromClass;所有 Swift 类型都可以转换为字符串。
  • 好人,谢谢你,我什至没有注意到,因为来自我的旧代码 +1
猜你喜欢
  • 2019-12-15
  • 2017-10-07
  • 1970-01-01
  • 2023-03-07
  • 2018-11-09
  • 2011-07-21
  • 2014-08-31
  • 2017-12-19
  • 1970-01-01
相关资源
最近更新 更多