如何从 SKScene 获取和更改我的视图控制器中的变量

Posted

技术标签:

【中文标题】如何从 SKScene 获取和更改我的视图控制器中的变量【英文标题】:How to get and change a variable in my view controller from SKScene 【发布时间】:2015-11-23 20:08:55 【问题描述】:

好的,下面是代码

class GameViewController:  UIViewController,  SceneTransitionDelegate, 
GKGameCenterControllerDelegate, ADBannerViewDelegate 

var coolbool:Bool = false

...abunch of unimportant stuff functions and stuff

 

这就是我想要从我的 SKScene 中做的事情

func thing1()

        let controller = GameViewController()
        controller.coolbool = true
        println(controller.coolbool) // Will say that it is true
        sceneDelegate.transitionToScene(Menu.self) //Menu.self is the skscene that
       we used to be in and will be in


func thing2()

        println(controller.coolbool) // Will say that it is false
        if (controller.coolbool == true)
        
           //Put rainbows over every sprite and change generator settings
        

所以基本上发生的事情是“coolbool”被初始化为假。直到 thing1() 被调用导致变量“coolbool”改变。我在过渡之后立即确认其更改。但是在转换之后(到同一个场景(如果布尔为真,我试图让它看起来不同))如果你问值是什么,它说它是假的......即使我只是将它设置为真.

无论如何,我认为我做错了什么,他们是更好的方法吗???如果你想要它这里是转换函数

func transitionToScene(sceneClass:Scene.Type) 
    playing = false
    var sizeRect = UIScreen.mainScreen().applicationFrame
    var width = sizeRect.size.width * UIScreen.mainScreen().scale
    var height = sizeRect.size.height * UIScreen.mainScreen().scale
    let skView = self.view as! SKView
    let scene = sceneClass(size: skView.bounds.size)
    scene.size = CGSizeMake(width, height)
    rwidth = width
    rheight = height
    swidth = width
    sheight = height
    skView.ignoresSiblingOrder = true

    scene.scaleMode = .AspectFill
    scene.sceneDelegate = self

    skView.presentScene(scene)

【问题讨论】:

在你的方法 thing1() 之外声明 let controller = GameViewController() @jtbandes 我真傻!这和coolbool是一回事,我重命名了它的所有实例,除了那个,我只是希望它易于人们阅读。 【参考方案1】:

你需要获取GameViewController的当前实例,所以这个语句:

let controller = GameViewController()

不会起作用,因为它声明了一个新的控制器实例,它与您当前使用的SKView 无关。相反,我们需要获取 当前的、正在呈现的视图控制器。

获取视图控制器的实例:

在这里可以帮助我们的最接近的方法是UIResponder 类,它是nextResponder:。它的一般功能是查找并返回当前的下一个响应者,这看起来很模糊,对我们来说没有多大用处,直到 Apple 提到:

子类必须重写这个方法来设置下一个响应者。 UIView 通过返回管理它的 UIViewController 对象(如果有)或其父视图(如果没有)来实现此方法

这意味着如果我们在一个场景中,我们可以通过使用场景的self.view 找到视图控制器,它是呈现的SKView 对象(继承自UIView)。我们所要做的就是在我们的响应者链中找到视图控制器。

斯威夫特:

var currentViewController: GameViewController?
var upstreamResponder: UIResponder? = self.view
var found = false

while (found != true)
    upstreamResponder = upstreamResponder!.nextResponder()
    if let viewController = upstreamResponder as? GameViewController 
        currentViewController = viewController
        found = true
    
    if upstreamResponder == nil 
        //could not find VC, PANIC!
        break
    

Objective-C:(可能必须#include "GameViewController.h")

GameViewController *currentViewController;
UIResponder *upstreamResponder = self.view;
BOOL found = false;

while (found != true) 
    upstreamResponder = [upstreamResponder nextResponder];
    if ([upstreamResponder isKindOfClass:[GameViewController class]]) 
        currentViewController = (GameViewController *)upstreamResponder;
    
    if (upstreamResponder == nil) 
        //omg where did VC go?!
        break;
    

在视图控制器上设置属性

现在您有了当前的视图控制器,设置任何所需的属性非常简单。所以如果你想改变coolbool,你所要做的就是状态:

currentViewController.coolbool = true

希望这会有所帮助! -最大

【讨论】:

以上是关于如何从 SKScene 获取和更改我的视图控制器中的变量的主要内容,如果未能解决你的问题,请参考以下文章

SKScene - 如何从 SKSpriteNode 获取类

如何正确调整 SKView 子视图和 SKScene 的大小

从 SKScene 呈现后无法关闭视图控制器

如何从 SKScene 到 UIViewController?

如何从 Sprite Kit 场景中引用当前的 Viewcontroller

从控制多个场景的视图控制器中禁用 uibutton