Swift3 如何从游戏场景编辑GameViewController的属性

Swift3 如何从游戏场景编辑GameViewController的属性,swift3,sprite-kit,Swift3,Sprite Kit,我希望在场景前面显示一个视图,以模拟文本框叙述。由于SklabelNode的局限性,我更喜欢使用UILabel的动画功能和文本换行功能 来自GameSecene.swift的代码 var viewController = GameViewController() override func didMove(to view: SKView) { viewController.printStuff() viewController.uiLabelContaine

我希望在场景前面显示一个视图,以模拟文本框叙述。由于SklabelNode的局限性,我更喜欢使用UILabel的动画功能和文本换行功能

来自GameSecene.swift的代码

var viewController = GameViewController()

override func didMove(to view: SKView) {

        viewController.printStuff()

        viewController.uiLabelContainer.isHidden = false

    }
来自GameViewController.swift的代码

override func viewDidLoad() {
        super.viewDidLoad()

        // Load 'GameScene.sks' as a GKScene. This provides gameplay related content
        // including entities and graphs.
        if let scene = GKScene(fileNamed: "GameScene") {

            // Get the SKScene from the loaded GKScene
            if let sceneNode = scene.rootNode as! GameScene? {

                // Copy gameplay related content over to the scene
                sceneNode.entities = scene.entities
                sceneNode.graphs = scene.graphs

                // Set the scale mode to scale to fit the window
                sceneNode.scaleMode = .aspectFill
                sceneNode.viewController = self
                // Present the scene
                if let view = self.view as! SKView? {
                    view.presentScene(sceneNode)
                    view.ignoresSiblingOrder = true

                    view.showsFPS = true
                    view.showsNodeCount = true
                }
            }
        }
        uiLabelContainer.isHidden = true

    }

func printStuff()  {
        print("this works, calling from gameviewcontroller")
    }

从gameviewcontroller调用函数可以工作,甚至可以打印UILabel上的内容(从其他类的变量或对象访问数据)。但是,将其中一个对象(uiLabelContainer)的属性从gameViewController更改为.isHidden=false似乎不起作用

之所以发生这种情况,是因为您在场景中使用以下行重新创建了
GameViewController

var viewController = GameViewController()
而不是获取已经存在的
GameViewController

有很多方法可以解决你的问题。 因此,例如,使用“hello world”精灵工具包模板,如果您将
GameViewController
作为游戏的初始viewController,则可以执行以下操作:

GameViewController: 游戏场景: 游戏场景2: (仅为测试而创建,以查看正确的
游戏场景
解除分配)


输出

谢谢你,伙计!这里的这行代码是:让appDelegate=UIApplication.shared.delegate为!AppDelegate如果让vc=AppDelegate.window?.rootViewController{self.viewController=vc as!GameViewController self.viewController.uiLabelContainer.isHidden=false}是键!!!你是救命恩人!:)我在网上搜寻这个。这绝对是这里的关键。让appDelegate=UIApplication.shared.delegate为!AppDelegate;如果让vc=appDelegate.window?.rootViewController{self.viewController=vc as!GameViewController}
import UIKit
import SpriteKit
class GameViewController: UIViewController {
    var uiLabelContainer:UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        uiLabelContainer = UILabel(frame: CGRect(x:0,y: 0,width: 250,height: 50))
        uiLabelContainer.textAlignment = NSTextAlignment.left
        uiLabelContainer.textColor = .white
        uiLabelContainer.text = "This is a Label"
        self.view.addSubview(uiLabelContainer)
        uiLabelContainer.isHidden = true
        if let view = self.view as! SKView? {
            if let scene = SKScene(fileNamed: "GameScene") {
                scene.scaleMode = .aspectFill
                view.presentScene(scene)
            }
            view.ignoresSiblingOrder = true
            view.showsFPS = true
            view.showsNodeCount = true
        }
    }
    func printStuff() {
        print("printStuff")
    }
}
import SpriteKit
class GameScene: SKScene {
    private var label : SKLabelNode?
    var viewController : GameViewController!
    override func didMove(to view: SKView) {
        self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
        if let label = self.label {
            label.alpha = 0.0
            label.run(SKAction.fadeIn(withDuration: 2.0))
        }
        self.run(SKAction.wait(forDuration: 2),completion:{[unowned self] in
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            if let vc = appDelegate.window?.rootViewController {
                self.viewController = vc as! GameViewController
                self.viewController.uiLabelContainer.isHidden = false
            }
        })
        self.run(SKAction.wait(forDuration: 5),completion:{[unowned self] in
            let scene2 = GameScene2()
            scene2.scaleMode = .aspectFill
            self.view?.presentScene(scene2)
        })
    }
    deinit {
        print("\n THE SCENE \((type(of: self))) WAS REMOVED FROM MEMORY (DEINIT) \n")
    }
}
import SpriteKit
class GameScene2: SKScene {
    private var label : SKLabelNode?
    override func didMove(to view: SKView) {
        print("gameScene2")
    }
}