Ios 使用UIKit元素(UIButtons、UILabel等)对SKScene进行场景转换

Ios 使用UIKit元素(UIButtons、UILabel等)对SKScene进行场景转换,ios,swift,uikit,sprite-kit,Ios,Swift,Uikit,Sprite Kit,我有一个菜单,它是一个SKScene,背景是SKSpriteNode,有3个ui按钮和1个ui标签 当用户单击按钮时,将触发此场景转换: view?.presentScene(GameScene(size: view!.bounds.size), transition: SKTransition.fadeWithDuration(2)) 场景确实发生了变化(背景也发生了变化),但所有元素仍在原地。 有没有合适的方法沿场景过渡移除它们?通过适当的方式,我的意思是垃圾收集器应该在某个时候从内存中释

我有一个菜单,它是一个SKScene,背景是SKSpriteNode,有3个ui按钮和1个ui标签

当用户单击按钮时,将触发此场景转换:

view?.presentScene(GameScene(size: view!.bounds.size), transition: SKTransition.fadeWithDuration(2))
场景确实发生了变化(背景也发生了变化),但所有元素仍在原地。
有没有合适的方法沿场景过渡移除它们?通过适当的方式,我的意思是垃圾收集器应该在某个时候从内存中释放菜单场景(如果菜单场景中仍有UIElements,则无法执行此操作)。

如果希望释放按钮,则必须将其从视图中移除

如果这真的有必要,这是值得考虑的吗?回收的内存量是否值得以后重新添加这些按钮的额外成本?假设您可以返回菜单

使用SpriteKit和UIKit元素进行视觉上有吸引力的转换有几个选项。虽然我不一定推荐他们

  • 通过调整或,在屏幕外手动设置按钮的动画
  • 从场景中删除过渡,并使用或设置UIView过渡的动画

  • 如果您无法使用这两个选项中的任何一个创建令人满意的效果,则可能需要重新实现场景/视图,以便仅使用SpriteKit元素。

    这里有两个选项。首先是继续使用UIKit元素,并在过渡到游戏场景时主动删除它们。例如,您可以设置在按下游戏按钮时执行相同操作的方法:

    func hideButtons () {
        //Hide your buttons and label here.
        btn.hidden = true //Either hide it
        btn.removeFromSuperview() //or remove it altogether.
        ... 
    }
    
    然后在呈现场景之前调用此方法

    self.hideButtons()
    view?.presentScene(GameScene(size: view!.bounds.size), transition: SKTransition.fadeWithDuration(2))
    
    或者,可以使用触摸代理在场景本身中实现一个按钮

    声明一个与按钮框架相同的SKSpriteNode。当您检测到触摸按钮时,触发场景更改


    另一个选项是使用类似的类。它的设置系统与UIButton非常相似。

    我假设您的UIKit元素已添加到视图中。如果希望它们消失,则需要将它们从视图中删除。如果我隐藏元素以在用户返回菜单场景时显示它们,我如何实际“弹出”级别场景以返回菜单?我必须
    presentScene
    对吗?但这将覆盖第一个菜单场景实例?您的SKScene类不应直接负责任何UIKit视图,传统上这是UIViewController的责任,因此,如果您的MenuScene被释放,然后在您返回应用程序中的菜单时重新分配,则不应出现任何问题。返回菜单后,您必须告诉视图控制器再次设置UIKit视图显示的动画。这是一种痛苦,也是我建议尽可能采用纯SpriteKit方法的原因之一。将所有相关逻辑封装到单独的场景或视图控制器中也可能更好。如果我隐藏按钮,则是在用户返回菜单场景时“取消隐藏”按钮。如何实现“返回”过渡?我是否需要一个全局变量
    menuScene
    可以在我的每个视图文件中访问(从那里我可以返回菜单)?为此,您需要一种方式使SKScene与UIViewController通信。看看这个答案,看看如何达到同样的效果: