23096


いつもお世話になっております。  
今回の質問は、表題の通りです。

現在野球のアプリを開発中の素人です。

詳細は下記の通りです。

投球が通過した場所をタップで指定。その場所にボールを表示(GameScene 以下 G)

タップしたゾーンがストライクかボールかを判別(G)

打者の動き（空振りとか見送り）をUISegmentedControlで指定(ViewController 以下 V)

その結果、ストライクかボールかを判別(V)

その結果をスコアボードに表示(V)

投球結果ボタンをタップ。OKなら投球を完了して、UISegmentedControlの結果をクリア。  
同時に表示したボールも消える(G)

次の投球待ち(V)

という具合にしたいのですが、  
そのボールを消すことができません。

この間のデータ（変数）はDelegateを使って、GからVに変数の受け渡しをしております。  
ですが、投球完了ボタンをタップした時に、VからGへの受け渡しがうまくいっていないようです。  
UISegConがVにあるのと、そのボタンをTabBarにStoryBoradを使っている関係で、表示したボールを消す時は、本当に一瞬だけ（ボールを消すため）だけにGに変数を渡し、すぐにGに戻ってくる必要があります。  
何か分かりやすい方法はありますか？  
（説明が下手ですみません）  
例えば、  
データの受け渡し（行ったり来たり）の際に、関数func()を使うとか？

よろしくお願いします。


CC BY-SA 3.0
2016-03-13T10:35:34.593
23089
2016-03-14T22:43:37.733
13156
question
swift
ViewControllerとGameSceneの間での数字の受け渡し


実は本当にわかりにくいので、全然ピント外れかも知れないのですが、階層構造のあるクラス間でのデータの受け渡しという話に絞らせていただきます。

通常の構成でSpriteKitのGameSceneを使用する場合、次のような階層構成になると思います。

[code]

    ViewController(UIViewController)
      |
      +-- SKView
            |
            +-- GameScene(SKScene)
    
[/code]

このような階層構造がある場合の設計の原則ですが、

  * 下位の階層は、上位の階層の詳細(publicなメンバーも含めて)に一切関知しない
  * 上位の階層は下位の階層の`public`な(*1)メンバー(メソッド・プロパティ)を参照して良い

とするものです。下位から上位(を含めて、階層不明のどこか)にアクセスする場合はdelegateを使うというのがApple流ですね。  
(Apple製フレームワークの`ViewController - (ちょっとややこしい)View -
(シンプルな)サブview`と言った構造も、概ねこの原則に従っています。)

と言うわけで、あなたの場合、下位(G)→上位(V)へは「Delegateを使って、GからVに変数の受け渡しをして」いるそうなので、この原則に従っていますから、逆向きも原則に従ってはいかがでしょうか。

具体的には、

  * GameScene側に「ボールを消す」ためのメソッド(なにか値を渡す必要があればパラメータを持つようにする)を`public`(`internal`でも良いですが)に定義する
  * ViewController側からはそのメソッドを呼ぶだけ

と言う形にすれば良いのではないかと思います。

*1 まだ`public`だの`private`だのは使い分けておられないかも知れませんが、「このプロパティの値をよそのクラスから自由に変えられちゃ困る」的なものは(概念的に)`private`なんだと思ってください。(そう言うのは実際に`private`にした方が良いです。)

(追記)コメントにいただいたことを踏まえてコード例を記載するとこんな感じになります。  
ViewControllerでボールを消す処理を入れるメソッドの中:

[code]

            let scene = (self.view as! SKView).scene as! GameScene
            scene.removeBall()
    
[/code]

GameSceneの中:

[code]

        func removeBall() {
            if let theNode = self.childNodeWithName("ball") {
                theNode.removeFromParent()
            }
        }
    
[/code]

(回答中では`public`を何箇所かに書いておいて、実際には`public`を付けていませんが、Swiftの場合、`public`修飾はframework作者以外にはあまり関係ないので、とりあえず`internal`(省略時のデフォルト)にしてあります。)

元質問で「Gに変数を渡し」あたりが何のことかわからないので、何かしら足りないこともあるかも知れませんが、例によって必要に応じコメントなどでお知らせください。


CC BY-SA 3.0
2016-03-13T12:50:32.913
23096
2016-03-14T22:43:37.733
2016-03-14T22:43:37.733
13972
13972
23089
answer