Как мога да отхвърля ViewController от моя GameScene.swift?

ВЪПРОС: Как мога да отхвърля ViewController от моя GameScene.swift?


СИТУАЦИЯ: Имам 2 VC в моята игра SpriteKit, така:

ViewController.swift ---- Натиснете Възпроизвеждане-----> GameViewController

Когато играчът загуби, искам да отхвърля GameViewController, така че играчът да може отново да натисне play. Проверявам за загуба на играча в моя GameScene.swift и бих искал да отхвърля GameVC от там.


N.B.: Търсих това в Google без успех.


КАКВО ОПИТАХ:

1) Създаване на екземпляр на gameVC в моя GameScene.swift и отхвърлянето му така:

let gameVC = GameViewController()
gameVC.dismissViewController(false,completion: nil)

2) Правене на:

self.view.window!.rootViewController?.dismissViewControllerAnimated(false, completion: nil)

Те не работят по очевидни причини ^^


person Coder1000    schedule 21.05.2016    source източник
comment
1) няма да работи: трябва да използвате съществуващия екземпляр, а не нов. 2) ще работи само ако self.view.window!.rootViewController? е вашият GameViewController екземпляр, но изглежда, че това вероятно е ViewController.   -  person Aaron Brager    schedule 21.05.2016
comment
@AaronBrager Да, знам :) Ето защо сложих това в раздела Какво опитах. Просто не виждам как да взема съществуващия екземпляр :/   -  person Coder1000    schedule 21.05.2016
comment
Трябва или да предадете GameScene препратка към контролера на изгледа, така че той да може да го отхвърли, или да използвате модела на делегат, за да комуникирате обратно на контролиращ обект, че VC трябва да бъде отхвърлен/отхвърлен сам   -  person Aaron Brager    schedule 21.05.2016
comment
@AaronBrager Поставете това в отговор, за да мога да го приема (ако работи) :D   -  person Coder1000    schedule 21.05.2016


Отговори (2)


Не искате да „грабвате“ съществуващия екземпляр: https://pragprog.com/articles/tell-dont-ask

Трябва или да предадете GameScene препратка към контролера на изгледа, така че той да може да го отхвърли, или да използвате модела на делегат, за да съобщите обратно на контролиращ обект, че VC трябва да бъде отхвърлен/отхвърлен сам.

Прост пример… можете да добавите свойство GameViewController към GameScene, след което да отхвърлите VC в подходящия момент:

class GameScene: SKScene {
    var gameVC: GameViewController?

    func gameDidEnd() {
        gameVC?.dismissViewControllerAnimated(true) {
            // if desired, do any cleanup after the VC is dismissed
        }
    }
}

След това просто задайте това свойство, когато създавате обекта GameScene на първо място:

if let gameScene = GameScene(fileNamed: "MyScene") {
    gameScene.gameVC = someGameVC
}

Този прост подход ще свърже тясно GameScene и GameViewController, което ще направи малко по-трудно, ако някога искате да използвате един от тези обекти без другия. Но за този прост случай на употреба може да е добре.

person Aaron Brager    schedule 21.05.2016
comment
Благодаря ви за отговора, но SO е против отговорите само с връзки, защото те могат да станат невалидни. Бихте ли могли да добавите кодов фрагмент, за да мога да приема отговора ви и да го подкрепя? :) - person Coder1000; 21.05.2016
comment
Разбира се, радвам се. Една секунда - person Aaron Brager; 21.05.2016
comment
Сега имам изтичане на памет, след като опитах това :/ - person Coder1000; 21.05.2016
comment
Може ли по-подробно? - person Aaron Brager; 21.05.2016
comment
Всеки път, когато загубя (отхвърлям GameVC, следователно се връщам към mainVC, където има бутона за възпроизвеждане) и играя отново, FPS пада. - person Coder1000; 21.05.2016
comment
Изглежда, че може да имате силен референтен цикъл. Можете да опитате weak var gameVC, ако е така. - person Aaron Brager; 21.05.2016
comment
Това беше! Мерси ! (Може би също редактирайте отговора си с weak?) - person Coder1000; 21.05.2016
comment
Не мислете, че трябва да редактирам отговора си — weak е необходимо само поради силния референтен цикъл, но това не се изисква нито от вашия въпрос, нито от моя отговор. - person Aaron Brager; 21.05.2016
comment
Добре, чудя се къде създадох този силен референтен цикъл :/ Винаги полагам допълнителни грижи, за да ги избегна, но този път изглежда ми убягна ›:) - person Coder1000; 21.05.2016
comment
Може би вашият контролер за изглед има силна препратка към сцената? - person Aaron Brager; 21.05.2016
comment
Може да обмислите използването на един контролер за изглед и подход с множество сцени. stackoverflow.com/a/35409586 - person Whirlwind; 31.05.2016

Проследих някои от вашите дискусии. Искам да добавя малко код, защото обикновено предпочитам да работя с един или два ViewController и много SKScene и SKNode, но в този случай може да е полезно да имам справка за currentViewController:

class MyModelScene: SKScene {
   let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
   var currentViewController : MyModelViewController! = MyModelViewController() 
 // MyModelViewController is a customized UIViewController

   override func didMoveToView(view: SKView) {
      super.didMoveToView(view)
      print("---")
      print("∙ \(NSStringFromClass(self.dynamicType))")
      print("---")
   }
}

class Level1Scene: MyModelScene {
    ...
}

В UIViewController:

class PreloadViewController: MyModelViewController {
     override func viewDidLoad() {
        super.viewDidLoad()

        if let scene = Level1Scene(fileNamed:"Level1Scene") {
            // Configure the view.
            let skView = self.view as! SKView
            skView.showsFPS = true
            skView.showsPhysics = true
            skView.showsNodeCount = true

            skView.ignoresSiblingOrder = true

            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .ResizeFill 
            scene.currentViewController = self
            skView.presentScene(scene)
        }
    }
}

С този код винаги имате препратка към currentViewController във вашия SKScene и можете да проверите дали това е правилният viewController, който искате да отхвърлите или не.

person Alessandro Ornano    schedule 30.05.2016
comment
Нямате нужда от NSStringFromClass; всички типове Swift могат да бъдат преобразувани в низове. - person Aaron Brager; 31.05.2016
comment
Добър човек, благодаря ти, дори не бях забелязал, защото идва от стария ми код +1 - person Alessandro Ornano; 31.05.2016