отказаться от SKScene вернуться в меню UIKit

Как только моя игра SpriteKit закончилась, я хотел бы вернуться в свой UIKit MenuViewController . Из того, что я узнал до сих пор, использование протокола / делегата является лучшим (?) Вариантом, но я не смог заставить это работать. Я знаю, что протокол, вероятно, перейдет выше объявления класса для GameViewController и будет выглядеть примерно так:

 protocol GameViewControllerDelegate { var gameOver: Bool? } 

Но мне нужна помощь, чтобы получить доступ к этому из GameScene и заставить его отклонить GameViewController . Ниже приведены кости приложения, если это помогает.

Изображение раскадровки

MenuViewController

 class MenuViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } @IBAction func goToGame(_ sender: UIButton) { performSegue(withIdentifier: "toGameSegue", sender: sender.currentTitle) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let destinationVC = segue.destination as? GameViewController { if let item = sender as? String { destinationVC.numberOfPlayers = item } } } } 

GameViewController

 class GameViewController: UIViewController { var numberOfPlayers: String? override func viewDidLoad() { super.viewDidLoad() if let view = self.view as! SKView? { if let scene = SKScene(fileNamed: "GameScene") { scene.scaleMode = .aspectFill scene.userData = NSMutableDictionary() scene.userData?.setObject(numberOfPlayers!, forKey: "numberOfPlayers" as NSCopying) view.presentScene(scene) } } } ... 

GameScene

 class GameScene: SKScene { var howManyPlayers: String? override func didMove(to view: SKView) { if let numPlayers = self.userData?.value(forKey: "numberOfPlayers") { howManyPlayers = numPlayers as? String } print(howManyPlayers!) } ... 

В этой игре SpriteKit есть MenuViewController, GameViewController и GameScene. Когда вы нажимаете кнопку из MenuViewController, данные отправляются через segue в GameViewController. Перед тем, как GameViewController представляет GameScene, он сохраняет данные в переменной userData сцены, чтобы GameScene мог получить к ней доступ. В этом примере это количество игроков.

Я согласен с комментариями Whirwind: почему смешивание двух разных фреймворков и усложнение вашей жизни, когда вы можете использовать один viewController только для выполнения всей вашей игры?

Во всяком случае, согласно вашему скриншоту на раскадровке, есть 2 viewControllers, и вы можете перейти ко второму viewController (и к GameScene ), только если вы нажмете кнопку .

Есть две вещи: освободить текущий SKScene (в вашем случае GameScene ) и представить «контроллер начального представления» или ваш MenuViewController .

Чтобы сделать это, я использую шаблон Hello Hello для SKSceneDelegate с поддержкой протокола / делегата для расширения класса SKSceneDelegate . Как вы можете видеть, мы можем уволить сцену (представляя нуль) и вызвать внешний метод на GameViewController для представления MainViewController

Чтобы быть уверенным, что обе эти операции будут успешными, я использую также два print только для отладки:

GameViewController :

 import UIKit import SpriteKit class GameViewController: UIViewController,TransitionDelegate { override func viewDidLoad() { super.viewDidLoad() if let view = self.view as! SKView? { if let scene = SKScene(fileNamed: "GameScene") { scene.scaleMode = .aspectFill scene.delegate = self as TransitionDelegate view.presentScene(scene) } view.ignoresSiblingOrder = true view.showsFPS = true view.showsNodeCount = true } } func returnToMainMenu(){ let appDelegate = UIApplication.shared.delegate as! AppDelegate guard let storyboard = appDelegate.window?.rootViewController?.storyboard else { return } if let vc = storyboard.instantiateInitialViewController() { print("go to main menu") self.present(vc, animated: true, completion: nil) } } } 

GameScene :

 import SpriteKit protocol TransitionDelegate: SKSceneDelegate { func returnToMainMenu() } class GameScene: SKScene { override func didMove(to view: SKView) { self.run(SKAction.wait(forDuration: 2),completion:{[unowned self] in guard let delegate = self.delegate else { return } self.view?.presentScene(nil) (delegate as! TransitionDelegate).returnToMainMenu() }) } deinit { print("\n THE SCENE \((type(of: self))) WAS REMOVED FROM MEMORY (DEINIT) \n") } } 

Выход :

введите описание изображения здесь

  • Как отклонить viewController в ios с помощью Swift
  • отображение видео, добавление поля UIText и сохранение его на альбоме iphone
  • Синхронизация CATransaction, вызванная внутри транзакции
  • Xcode восстанавливается постоянно после реализации класса
  • Отключить клавиатуру с жестом салфетки
  • Как перечислить и удалить сохраненные учетные данные в Swift
  • Как обрабатывать ошибки в NSPersistentContainer.loadPersistentStores?
  • NSGenericException при добавлении некоторых ограничений программно
  • Вложенный UITableView переменной высоты в UITableViewCell + UITableViewAutomaticDimension
  • Как сделать назначенный инициализатор для подкласса NSManagedObject в Swift?
  • Swift iOS: EXC_BAD_INSTRUCTION
  • Давайте будем гением компьютера.