質問: 物理のシミュレートアプリを作成したいのですが、 UISwitchの実装に関して調べてもわかりませんでした。 ディレクトリ/ファイル構成は以下の画像通りです。 ![ディレクトリ/ファイル構成](https://i.stack.imgur.com/cIqOA.png) ■やりたいこと 1.GameViewControllerのUISwitchのBool情報をGameSceneで取得したい こちらではGameViewControllerのUISwitchのインスタンスをGameSceneクラスで 取得したいのですが、良い例が見つからず困っております。 2.もしくはGameScene内にUISwitchのインスタンスを紐付けたい GameSceneクラス内にoutletの紐付けを行うとThread 1:signal SIGABRT が出てしまいます。これはGameViewControllerの下にUISwitchを配置したからだと 思います。 もしGameScene内にUISwitchのインスタンスを紐付けたいとなるとどのような実装になるでしょうか。
回答: 質問にお答えする前に、AppleのGUI(Graphics User Interface)の基本的な考え方は、ゲームの構成パーツの中に、UIKitのパーツを使わないというものであったと、私は記憶しています。いつどこでそれを読んだのか、昔すぎて定かではありませんし、Appleの公式ドキュメントから探し出すのも、かなわなかったので、不確かな情報としてしかお示しできないのが残念ですが、ゲームの世界は、外部(UIKitのGUIデザイン)の世界からはっきり切り離されているべきであるという考え方に依拠しているのであれば、納得していただけるのではないでしょうか? なので、回答は、「`UISwitch`に相当するコントロールを、オリジナルで、`SKNode`から作成する」ということになりますが、それでは元も子もないので、質問にそのまま即した回答を書いておこうと思います。 Storyboardを使うにしろ、コードで実装するにしろ、`UIViewController`のサブクラスを、`SKScene`のサブクラスに置き換えることはできません。この二つのクラスは、`UIResponder`のサブクラスであるという共通点を除いては、互いに継承関係がありません。 なので、`GameViewController`から`GameScene`に「`UISwitch`の`Bool`情報」を受け渡すという方法をとることを考えます。 !画像の説明をここに入力 このようなStoryboardの構成をして、以下のコードを記述し、接続します。 ViewController.swift ``` import UIKit import SpriteKit class ViewController: UIViewController { @IBOutlet weak var gameView: SKView! @IBOutlet weak var paramSwitch: UISwitch! override func viewDidLoad() { super.viewDidLoad() // GameSceneインスタンスを作成し、gameView上に表示する。 let gameScene = GameScene(size: CGSize(width: 343, height: 580)) gameScene.scaleMode = .aspectFit // GameSceneのプロパティparamをスイッチの値にセットする。 gameScene.param = paramSwitch.isOn gameView.presentScene(gameScene) } // スイッチの切り替えで、GameSceneのプロパティparamの値を変える。 @IBAction func setParam(_ sender: UISwitch) { if let gameScene = gameView.scene as? GameScene { gameScene.param = sender.isOn } } } ``` GameScene.swift ``` import UIKit import SpriteKit class GameScene: SKScene { // スイッチの値を受け取るプロパティparamを定義。 var param: Bool = false { didSet { if let aNode = childNode(withName: "Parameter") as? SKShapeNode { // スイッチがOnなら緑に、Offなら赤に。 aNode.fillColor = param ? .green : .red } } } override func didMove(to view: SKView) { backgroundColor = UIColor.blue // プロパティparamの値を視覚化するparamNodeを作成し、貼り付け。 let paramNode = SKShapeNode(circleOfRadius: 24) paramNode.strokeColor = UIColor.clear // スイッチがOnなら緑に、Offなら赤に。 paramNode.fillColor = param ? .green : .red paramNode.name = "Parameter" paramNode.position = CGPoint(x: 150, y: 150) addChild(paramNode) } } ``` スイッチを切り替えると、`SKShapeNode`の`paramNode`が、赤色、緑色で切り替わることが確認できると思います。 なお、方法は、この一通りではありません。アイデア次第で色々な方法をとることができるでしょう。