从SKScene到故事板的观察创建旧场景的实例

时间:2023-01-22 23:12:53

Here is my storyboard showing a segue to a UINavigationController:

这是我的故事板显示到UINavigationController的segue:

从SKScene到故事板的观察创建旧场景的实例

I fade out my game scene and call this segue from my SKScene like so:

我逐渐淡出我的游戏场景并从我的SKScene中调用这个segue:

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

The nav controller moves a UIViewController on top of the game scene, as expected. But during the transition, I can see two new instances of the SKScene popping up in the background before the transition finishes and they are covered up by the new view controller. A print statement in my scene's didMove(to view:) method confirms that an SKScene object is appearing twice.

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

I can't figure out why my SKScene subclass is automatically being called twice after it triggers a segue. I also tried presenting the view controller like so but had the same issue:

我无法弄清楚为什么我的SKScene子类在触发segue后会被自动调用两次。我也试过像这样呈现视图控制器,但有同样的问题:

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

I have a cludgy workaround in mind but I'd rather understand what is causing this to happen so I can prevent it. Any ideas?

我有一个狡猾的解决方法,但我宁愿明白是什么导致这种情况发生,所以我可以阻止它。有任何想法吗?

UPDATE:

更新:

I suspect the reason has something to do with a passage from this Apple doc:

我怀疑这个原因与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.

使用UIModalPresentationFullScreen样式呈现视图控制器时,UIKit通常会在过渡动画完成后删除基础视图控制器的视图。您可以通过指定UIModalPresentationOverFullScreen样式来阻止删除这些视图。当呈现的视图控制器具有允许底层内容显示的透明区域时,您可以使用该样式。

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.

使用其中一种全屏演示样式时,启动演示的视图控制器本身必须覆盖整个屏幕。如果呈现视图控制器未覆盖屏幕,UIKit会向上查看控制器层次结构,直到找到它为止。如果找不到填充屏幕的中间视图控制器,UIKit将使用窗口的根视图控制器。

You can see in my screenshot that GameViewController is my initial view controller. This is where I am calling the segue from. Like the doc says, maybe UIKit is removing the underlying content (the SKView that is presenting my game scene) when the segue is called. But I am using a full-screen presentation style, and UIKit requires that the scene's view controller must cover the screen. Since it was removed by UIKit, then UIKit goes up the view hierarchy and finds GameViewController which it calls to display.

您可以在我的屏幕截图中看到GameViewController是我的初始视图控制器。这就是我从中调用segue的地方。就像医生说的那样,也许UIKit在调用segue时会删除底层内容(呈现我的游戏场景的SKView)。但我使用的是全屏演示风格,UIKit要求场景的视图控制器必须覆盖屏幕。由于它被UIKit删除,然后UIKit上升视图​​层次结构并找到它调用的GameViewController。

I'm making a lot of assumptions, but seems like that might explain why my game scene is being recreated twice (or once... I had different results in my testing) while it calls a segue and waits for the transition to finish.

我做了很多假设,但似乎这可以解释为什么我的游戏场景被重新创建两次(或者一次......我的测试中有不同的结果),而它调用了一个segue并等待过渡完成。

Also, I noticed that if I change the segue I'm using from Show to Present Modally, Over Full Screen, then the issue does not occur. That seems to support my guess.

此外,我注意到,如果我改变了我正在使用的模式,从模式显示模式,全屏模式,那么问题就不会发生。这似乎支持了我的猜测。

1 个解决方案

#1


2  

Well, after our conversation it turns out that it uses the same instance of GameViewController. So in your case you just workaround it. It's happening because your second view controller somehow not covering the entire screen (or it has opacity), and the system layout again the GameViewController. As you quoted:

好吧,在我们的谈话之后,它发现它使用相同的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.

使用其中一种全屏演示样式时,启动演示的视图控制器本身必须覆盖整个屏幕。如果呈现视图控制器未覆盖屏幕,UIKit会向上查看控制器层次结构,直到找到它为止。如果找不到填充屏幕的中间视图控制器,UIKit将使用窗口的根视图控制器。

For others i'll keep some of the old answer:

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

When you segue to a view controller you always creates a new instance. (So if you want to reuse the instance, don't use segues!)

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

When you present, you always shows it modally.

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

When you show you move to another view controller.

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

#1


2  

Well, after our conversation it turns out that it uses the same instance of GameViewController. So in your case you just workaround it. It's happening because your second view controller somehow not covering the entire screen (or it has opacity), and the system layout again the GameViewController. As you quoted:

好吧,在我们的谈话之后,它发现它使用相同的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.

使用其中一种全屏演示样式时,启动演示的视图控制器本身必须覆盖整个屏幕。如果呈现视图控制器未覆盖屏幕,UIKit会向上查看控制器层次结构,直到找到它为止。如果找不到填充屏幕的中间视图控制器,UIKit将使用窗口的根视图控制器。

For others i'll keep some of the old answer:

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

When you segue to a view controller you always creates a new instance. (So if you want to reuse the instance, don't use segues!)

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

When you present, you always shows it modally.

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

When you show you move to another view controller.

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