从 SKScene 转到故事板,创建旧场景的实例

Segue from SKScene to storyboard creating instances of old scene

这是我的故事板,展示了 UINavigationController:

我淡出我的游戏场景并从我的 SKScene 中调用这个 segue,如下所示:

mainVC?.performSegue(withIdentifier: "tySeg", sender: nil)

导航控制器按预期在游戏场景顶部移动 UIViewController。但是在转换期间,我可以看到 SKScene 的两个新实例在转换完成之前在后台弹出,并且它们被新的视图控制器覆盖了。我场景的 didMove(to view:) 方法中的打印语句确认 SKScene 对象出现了两次。

我不明白为什么我的 SKScene 子类在触发 segue 后自动被调用两次。我也试过像这样展示视图控制器,但遇到了同样的问题:

mainVC?.present(navVC, animated: false, completion: nil)

我有一个笨拙的解决方法,但我宁愿了解导致这种情况发生的原因,以便我可以阻止它。有什么想法吗?

更新:

我怀疑原因与this Apple doc的一段话有关:

When presenting a view controller using the UIModalPresentationFullScreen style, UIKit normally removes the views of the underlying view controller after the transition animations finish. You can prevent the removal of those views by specifying the UIModalPresentationOverFullScreen style instead. You might use that style when the presented view controller has transparent areas that let underlying content show through.

When using one of the full-screen presentation styles, the view controller that initiates the presentation must itself cover the entire screen. If the presenting view controller does not cover the screen, UIKit walks up the view controller hierarchy until it finds one that does. If it can’t find an intermediate view controller that fills the screen, UIKit uses the root view controller of the window.

您可以在我的屏幕截图中看到 GameViewController 是我的初始视图控制器。这就是我打电话给 segue 的地方。就像文档所说的那样,当调用 segue 时,UIKit 可能会删除底层内容(呈现我的游戏场景的 SKView )。但是我使用的是全屏呈现方式,UIKit 要求场景的视图控制器必须覆盖屏幕。由于它已被 UIKit 删除,因此 UIKit 会在视图层次结构中向上移动并找到它调用以显示的 GameViewController

我做了很多假设,但这似乎可以解释为什么我的游戏场景在调用 segue 并等待过渡到完成。

另外,我注意到如果我将我正在使用的 segue 从 Show 更改为 Present Modally, Over Full Screen,那么问题就不会发生。这似乎支持了我的猜测。

好吧,在我们的谈话之后发现它使用了相同的 GameViewController 实例。 所以在你的情况下你只是解决它。发生这种情况是因为您的第二个视图控制器不知何故没有覆盖整个屏幕(或者它具有不透明度),并且系统布局又是 GameViewController。正如你引用的那样:

When using one of the full-screen presentation styles, the view controller that initiates the presentation must itself cover the entire screen. If the presenting view controller does not cover the screen, UIKit walks up the view controller hierarchy until it finds one that does. If it can’t find an intermediate view controller that fills the screen, UIKit uses the root view controller of the window.

对于其他人,我将保留一些旧答案:

当您 segue 到视图控制器时,您总是会创建一个新实例。 (所以如果你想重用实例,不要使用 segues!)

当你present时,你总是以模态显示它。

当您 show 移动到另一个视图控制器时。