質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.63%

【Swift,Xcode】Buttonで格納したはずの文字列がUILabelに表示されない

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,188

nekokichi

score 38

 前提・実現したいこと

「ChoiceViewController」
イメージ説明

「ResultViewController」
!イメージ説明

1つ目の画面にある、上右下左のいずれかを押したら、
2つ目の画面にある、「あなた」の下部に選択した矢印が表示され、
「ホイッ!!」の下部にはランダムに選択された矢印が表示されるようにしたいです。

上右下左のいずれかをタップすると、ResultViewControllerに切り替わる仕組みになってます。

 発生している問題・エラーメッセージ

ソースコードでは、合っているはずなんですが、ResultViewControllerの「ホイッ!!」と「あなた」のそれぞれの下部に配置したUILabelがなぜか表示されません。

原因がわからずつまづいています。

どうかご回答よろしくお願いします。

 該当のソースコード

**「ChoiceViewController」
**
import UIKit

class ChoiceHandViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        random_cpuHand()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //上右下左の手を用意
    let Hand = ["⬆︎","➡︎","⬇︎","⬅︎"]

    //プレイヤーの手
    var Player_Hand = ""

    //CPUの手
    var CPU_Hand = ""

    //CPUの手をランダムに選択
    //配列の番号にUInt32は使えない!?
    func random_cpuHand() {
        let random = Int(arc4random_uniform(4))
        CPU_Hand += Hand[random]
    }

    //上を選択
    @IBAction func UpButton(_ sender: Any) {
        Player_Hand += Hand[0]
    }

    //右を選択
    @IBAction func RightButton(_ sender: Any) {
        Player_Hand += Hand[1]
    }

    //下を選択
    @IBAction func DownButton(_ sender: Any) {
        Player_Hand += Hand[2]
    }

    //左を選択
    @IBAction func LeftButton(_ sender: Any) {
        Player_Hand += Hand[3]
    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}


**「ResultViewController」**

import UIKit

class ResultViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        displayresult()
        result()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBOutlet weak var CPULabel: UILabel!

    @IBOutlet weak var PlayerLabel: UILabel!

    //勝敗の判定を表す変数
    var winorlose = ""

    //スコアを保持する変数
    var score = 0

    //ChoiceHandViewControllerのインスタンスを作成
    let choice_instance = ChoiceHandViewController()

    //勝敗を判定する処理
    func result() {
        if choice_instance.Player_Hand == choice_instance.CPU_Hand {
            winorlose = "lose"
        } else {
            winorlose = "win"
            score += 1
        }
    }

    //両者の手を表示
    func displayresult() {
        //プレイヤーの手を表示
        PlayerLabel.text = choice_instance.Player_Hand
        //CPUの手を表示
        CPULabel.text = choice_instance.CPU_Hand
    }

    //プレイヤーが勝ちなら前画面に戻る、負けならゲーム終了
    @IBAction func changeViewButton(_ sender: Any) {
        if winorlose == "win" {
            performSegue(withIdentifier: "Win", sender: nil)
        } else if winorlose == "lose" {
            performSegue(withIdentifier: "Lose", sender: nil)
        }

    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

 試したこと

・ChoiceViewControllerの@IBActionに、print(Player_Hand)を追加したら、確かにPlayer_Handには選択した矢印が表示されていました。

・    func displayresult() {
//プレイヤーの手を表示
PlayerLabel.text = choice_instance.Player_Hand
//CPUの手を表示
CPULabel.text = choice_instance.CPU_Hand
print(choice_instance.Player_Hand)
print(choice_instance.CPU_Hand)
}
のように記述しましたが、コンソール画面には何も表示されませんでした。

 補足情報(FW/ツールのバージョンなど)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2018/08/21 12:59 編集

    (deleted)

    キャンセル

  • fuzzball

    2018/08/21 15:51

    ChoiceHandViewControllerからResultViewControllerには、どうやって遷移していますか?

    キャンセル

回答 2

checkベストアンサー

+1

let choice_instance = ChoiceHandViewController()

これは新規にインスタンスを生成していますので、当然Player_HandCPU_Handもカラです。
新規に生成するのでははなく、生成済のインスタンスを取得して下さい。(もしくはPlayer_HandCPU_Handを受け取るか)

 追記

ボタンのAction SegueのShowで遷移していると仮定して。

class ResultViewController: UIViewController {
    :
    //ChoiceHandViewControllerのインスタンスを作成
    //let choice_instance = ChoiceHandViewController() //※これは使わない
    :    
    override func viewDidLoad() {
        super.viewDidLoad()

        //ここでは取得しない
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        //viewDidLoad()ではpresentingViewControllerを取得できないので、ここで取得する
        displayresult()
        result()
    }

    //両者の手を表示
    func displayresult() {

        //ChoiceHandViewControllerのインスタンスから、それぞれの手を取得する
        if let choice_instance = self.presentingViewController as? ChoiceHandViewController {
            //プレイヤーの手を表示
            PlayerLabel.text = choice_instance.Player_Hand
            //CPUの手を表示
            CPULabel.text = choice_instance.CPU_Hand
        } else {
            //念のため取得失敗の処理
            PlayerLabel.text = "?"
            CPULabel.text = "?"
        }
    }
    :
}

これもあまりいい方法とは言えません。

最初にもチラと書きましたが、ResultViewController側にPlayer_HandCPU_Handを持たせて、ChoiceHandViewControllerからResultViewControllerに結果を渡す方がいいです。
遷移時の値の受け渡しにはprepare(for:sender:)を使います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/21 13:12

    ご回答ありがとうございます。

    生成済みのインスタンスの定型文を教えていただけますか?

    お手数をかけて申し訳ありません。

    キャンセル

  • 2018/08/21 16:01

    無事解決しました。
    お手数をかけて申し訳ありませんでした。
    2度とこのようなことがないようにします。

    キャンセル

  • 2018/08/21 16:05

    bokuranokyoさんの回答で解決しようとしているのでしたら、やめておいた方がいいです。
    「質問への追記・修正」の質問への返答をお願いします。

    キャンセル

  • 2018/08/21 16:57

    遷移時に値を渡せるメソッドを最初から使えてれば、もっと楽に記述できたかもしれませんね。
    もっと詳しくググればよかったですね。
    prepareメソッドを教えていただきありがとうございました。

    キャンセル

0

まずChoiceHandViewControllerの変更点
ChoiceHandViewControllerのクラス外でインスタンスを作成しておく

//ChoiceHandViewController

var result = ChoiceHandViewController()

class ChoiceHandViewController: UIViewController {
//省略

各変数の前にresult(作成したインスタンス)を加える

//ChoiceHandViewController

func random_cpuHand() {
        let random = Int(arc4random_uniform(4))
        result.CPU_Hand += Hand[random]
    }

    //上を選択
    @IBAction func UpButton(_ sender: Any) {
        result.Player_Hand += Hand[0]
    }

    //右を選択
    @IBAction func RightButton(_ sender: Any) {
        result.Player_Hand += Hand[1]
    }

    //下を選択
    @IBAction func DownButton(_ sender: Any) {
        result.Player_Hand += Hand[2]
    }

    //左を選択
    @IBAction func LeftButton(_ sender: Any) {
        result.Player_Hand += Hand[3]
    }

次はResultViewControllerの変更点

class ResultViewController: UIViewController {

    let choice_instance = result

    override func viewDidLoad() {
        super.viewDidLoad()

        print(choice_instance.Player_Hand)
        print(choice_instance.CPU_Hand)

    }

多分あまり綺麗なやり方ではないですが、とりあえず動いて次に進めたいのであればこんな感じでいけると思います。
動かなかったらすいません!
エラーに負けず頑張ってください!!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/21 15:45

    ありがとうございます!!
    無事、動作してくれました!!

    申し訳ありませんが、お答えしていただけますか?

    1)なぜ、let choice_instance = result、によってChoiceViewControllerのインスタンスをResultViewContollerに渡せたのか?
    2)なぜ、ChoiceViewControllerにおいて、var result = ChoiceHandViewController()、の必要があったのか?
    3)なぜ、var result = ChoiceHandViewController()、をclassよりも上の方に記述したのか?

    できれば疑問を解決してから次に行きたいので、1つでも構いませんので、上記の質問にお答えしていただけますか?

    よろしくお願いします!!

    キャンセル

  • 2018/08/21 16:00

    動作してよかったです!!

    それがお恥ずかしいことに自分も体系的に学んできたわけではないので詳しくは答えられません、、
    3)に関しては、そもそもインスタンスはclassの外に書くものなので上に書いておきました。

    キャンセル

  • 2018/08/21 16:01

    全然知りませんでした..。
    本当に助かりました!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る