Ios 从场景切换到故事板,创建旧场景的实例

Ios 从场景切换到故事板,创建旧场景的实例,ios,swift,sprite-kit,segue,skscene,Ios,Swift,Sprite Kit,Segue,Skscene,这是我的故事板,显示了一个UINavigationController: 我淡出我的游戏场景,从我的SKScene中调用此segue,如下所示: mainVC?.performSegue(withIdentifier: "tySeg", sender: nil) 导航控制器按预期在游戏场景顶部移动一个UIViewController。但是在转换过程中,我可以看到在转换完成之前背景中弹出了两个新的SKScene实例,它们被新的视图控制器覆盖。我的场景的didMove(to view:)方法中的

这是我的故事板,显示了一个
UINavigationController

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

mainVC?.performSegue(withIdentifier: "tySeg", sender: nil)
导航控制器按预期在游戏场景顶部移动一个
UIViewController
。但是在转换过程中,我可以看到在转换完成之前背景中弹出了两个新的
SKScene
实例,它们被新的视图控制器覆盖。我的场景的
didMove(to view:)
方法中的print语句确认
SKScene
对象出现两次

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

mainVC?.present(navVC, animated: false, completion: nil)
我心里有一个棘手的解决办法,但我更想知道是什么导致了这种情况的发生,这样我才能防止它。有什么想法吗

更新:

我怀疑原因与以下文章有关:

使用显示视图控制器时
UIModalPresentationFullScreen
style,UIKit通常会删除视图 转换动画后的基础视图控制器的 结束。可以通过指定
UIModalPresentationOverFullScreen
style。你可以用这个 显示的视图控制器具有透明区域时的样式 让底层内容显示出来

使用其中一种全屏演示样式时,视图 发起演示文稿的控制器本身必须覆盖 整个屏幕。如果显示视图控制器未覆盖 屏幕上,UIKit沿视图控制器层次结构向上移动,直到找到 是的。如果找不到中间视图控制器 填充屏幕,UIKit使用窗口的根视图控制器

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

我做了很多假设,但这似乎可以解释为什么我的游戏场景在调用segue并等待转换完成时被重新创建了两次(或者一次…我在测试中得到了不同的结果)


另外,我注意到,如果我将使用的序列从
Show
更改为
Present Modally,全屏显示,则不会出现问题。这似乎支持我的猜测。

好吧,在我们的对话之后,它使用的是同一个GameViewController实例。 因此,在你的情况下,你只是解决它。这是因为你的第二个视图控制器没有覆盖整个屏幕(或者不透明度),而系统布局又是GameViewController。正如你所引述:

使用其中一种全屏演示样式时,视图 发起演示文稿的控制器本身必须覆盖 整个屏幕。如果显示视图控制器未覆盖 屏幕上,UIKit沿视图控制器层次结构向上移动,直到找到 是的。如果找不到中间视图控制器 填充屏幕,UIKit使用窗口的根视图控制器

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

当您
segue
到视图控制器时,始终会创建一个新实例(因此,如果要重用实例,请不要使用segues!)

当您
呈现时
,您总是以模式显示它


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

谢谢,这些提示有助于理解VC的创建。但是主要的问题是为什么底层的
SKScene
在我不希望它被实例化的时候被实例化了。我之前做了一些,并用我怀疑的答案更新了我的问题,但我希望有人能证实这一点。当segue触发时,GVC的
视图将消失
方法被调用。然后紧接着(当segue还在进行中时),GVC的
viewWillLayoutSubviews
方法被调用,表示正在创建一个新的GVC(并且我可以在segue完成之前看到一个新的游戏场景出现)。我怀疑,正如我在更新的问题中引用的苹果文档所建议的那样,UIKit正在自动调用GVC。我不确定它是否创建了两次。我认为它使用了全球价值链的相同实例。请在GVC中创建一个静态int-var(值为0),然后在每次调用任何一个GVC构造函数时递增该var。如果您不想添加变量,可以使用断点进行调试,只需在GVC的
viewWillLayoutSubviews
中添加,并且变量已递增。这告诉我,这和你说的是同一个例子。现在我在想,可能两次调用GVC的原因是因为segue要求底层场景的视图控制器再次布局其子视图。这可能解释了为什么会调用两次
viewWillLayoutSubviews
。我的解决方法是以编程方式隐藏场景的内容,但这不是最好的方法。最简单的方法就是简单地选择不同风格的segue。谢谢你的帮助!如果你想更新你的答案,我可以接受它作为解决方案。或者,如果你愿意,我可以自己编辑它,添加苹果的报价和解释:)为了澄清,我可以通过全屏使用
来避免这个问题。但真正的问题是为什么要自动实例化
SKScene