質問: いつもお世話になっております。 今回の質問は、表題の通りです。 現在野球のアプリを開発中の素人です。 詳細は下記の通りです。 投球が通過した場所をタップで指定。その場所にボールを表示(GameScene 以下 G) タップしたゾーンがストライクかボールかを判別(G) 打者の動き(空振りとか見送り)をUISegmentedControlで指定(ViewController 以下 V) その結果、ストライクかボールかを判別(V) その結果をスコアボードに表示(V) 投球結果ボタンをタップ。OKなら投球を完了して、UISegmentedControlの結果をクリア。 同時に表示したボールも消える(G) 次の投球待ち(V) という具合にしたいのですが、 そのボールを消すことができません。 この間のデータ(変数)はDelegateを使って、GからVに変数の受け渡しをしております。 ですが、投球完了ボタンをタップした時に、VからGへの受け渡しがうまくいっていないようです。 UISegConがVにあるのと、そのボタンをTabBarにStoryBoradを使っている関係で、表示したボールを消す時は、本当に一瞬だけ(ボールを消すため)だけにGに変数を渡し、すぐにGに戻ってくる必要があります。 何か分かりやすい方法はありますか? (説明が下手ですみません) 例えば、 データの受け渡し(行ったり来たり)の際に、関数func()を使うとか? よろしくお願いします。
回答: 実は本当にわかりにくいので、全然ピント外れかも知れないのですが、階層構造のあるクラス間でのデータの受け渡しという話に絞らせていただきます。 通常の構成でSpriteKitのGameSceneを使用する場合、次のような階層構成になると思います。 ``` ViewController(UIViewController) | +-- SKView | +-- GameScene(SKScene) ``` このような階層構造がある場合の設計の原則ですが、 * 下位の階層は、上位の階層の詳細(publicなメンバーも含めて)に一切関知しない * 上位の階層は下位の階層の`public`な(*1)メンバー(メソッド・プロパティ)を参照して良い とするものです。下位から上位(を含めて、階層不明のどこか)にアクセスする場合はdelegateを使うというのがApple流ですね。 (Apple製フレームワークの`ViewController - (ちょっとややこしい)View - (シンプルな)サブview`と言った構造も、概ねこの原則に従っています。) と言うわけで、あなたの場合、下位(G)→上位(V)へは「Delegateを使って、GからVに変数の受け渡しをして」いるそうなので、この原則に従っていますから、逆向きも原則に従ってはいかがでしょうか。 具体的には、 * GameScene側に「ボールを消す」ためのメソッド(なにか値を渡す必要があればパラメータを持つようにする)を`public`(`internal`でも良いですが)に定義する * ViewController側からはそのメソッドを呼ぶだけ と言う形にすれば良いのではないかと思います。 *1 まだ`public`だの`private`だのは使い分けておられないかも知れませんが、「このプロパティの値をよそのクラスから自由に変えられちゃ困る」的なものは(概念的に)`private`なんだと思ってください。(そう言うのは実際に`private`にした方が良いです。) (追記)コメントにいただいたことを踏まえてコード例を記載するとこんな感じになります。 ViewControllerでボールを消す処理を入れるメソッドの中: ``` let scene = (self.view as! SKView).scene as! GameScene scene.removeBall() ``` GameSceneの中: ``` func removeBall() { if let theNode = self.childNodeWithName("ball") { theNode.removeFromParent() } } ``` (回答中では`public`を何箇所かに書いておいて、実際には`public`を付けていませんが、Swiftの場合、`public`修飾はframework作者以外にはあまり関係ないので、とりあえず`internal`(省略時のデフォルト)にしてあります。) 元質問で「Gに変数を渡し」あたりが何のことかわからないので、何かしら足りないこともあるかも知れませんが、例によって必要に応じコメントなどでお知らせください。