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

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

ただいまの
回答率

87.48%

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 570

score 12

Swift4:csvファイルを読み込みテキストビューに表示

Xcode(Swift4)でクイズアプリを作っています。
nilに問題があるとまでわかりましたが、解決には至りませんでした。。
ビルドを実行しようとしたさいに以下のエラーメッセージが発生しました。

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

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

該当のソースコード

questionNoLabel.text = "Q.\(questionData.questionNo)"の部分

//
//  QuestionViewController.swift
//  financial
//
//  Created by てつや on 2019/06/09.
//  Copyright © 2019年 tetsuya. All rights reserved.
//

import UIKit
import AudioToolbox

class QuestionViewController: UIViewController {

    var questionData: QuestionData!

    @IBOutlet weak var questionNoLabel: UILabel! // 問題番号ラベル
    @IBOutlet weak var questionTextView: UITextView! //問題文
    @IBOutlet weak var answer1Button: UIButton!          // 選択肢1ボタン
    @IBOutlet weak var answer2Button: UIButton!          // 選択肢2ボタン
    @IBOutlet weak var answer3Button: UIButton!          // 選択肢3ボタン
    @IBOutlet weak var answer4Button: UIButton!          // 選択肢4ボタン


    @IBOutlet weak var correctImageView: UIImageView!    // 正解時のイメージビュー
    @IBOutlet weak var incorrectImageView: UIImageView!  // 不正解時のイメージビュー

    override func viewDidLoad(){
        super.viewDidLoad()
        //初期データ設定処理。前画面で設定済のquestionDataから値を取り出す
        questionNoLabel.text = "Q.\(questionData.questionNo)"

        questionTextView.text = questionData.question

        answer1Button.setTitle(questionData.answer1, for: UIControlState.normal)
        answer2Button.setTitle(questionData.answer2, for: UIControlState.normal)
        answer3Button.setTitle(questionData.answer3, for: UIControlState.normal)
        answer4Button.setTitle(questionData.answer4, for: UIControlState.normal)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    //選択技1をタップ
    @IBAction func tapAnswer1Button(_ sender: Any){
        questionData.userChoiceAnswerNumber = 1 //選択した答えを保存する
        goNextQuestionWithAnimation() //次の問題に進む
    }

    //選択技2をタップ
    @IBAction func tapAnswer2Button(_ sender: Any){
        questionData.userChoiceAnswerNumber = 2 //選択した答えを保存する
        goNextQuestionWithAnimation() //次の問題に進む
    }

    //選択技3をタップ
    @IBAction func tapAnswer3Button(_ sender: Any){
        questionData.userChoiceAnswerNumber = 3 //選択した答えを保存する
        goNextQuestionWithAnimation() //次の問題に進む
    }

    //選択技4をタップ
    @IBAction func tapAnswer4Button(_ sender: Any){
        questionData.userChoiceAnswerNumber = 4 //選択した答えを保存する
        goNextQuestionWithAnimation() //次の問題に進む
    }
    // 次の問題にアニメーション付きで進む
    func goNextQuestionWithAnimation() {
        // 正解しているか判定する
        if questionData.isCorrect() {
            // 正解のアニメーションを再生しながら次の問題へ遷移する
            goNextQuestionWithCorrectAnimation()
        } else {
            // 不正解のアニメーションを再生しながら次の問題へ遷移する
            goNextQuestionWithIncorrectAnimation()
        }
    }

    // 次の問題に正解のアニメーション付きで遷移する
    func goNextQuestionWithCorrectAnimation() {
        // 正解を伝える音を鳴らす
        AudioServicesPlayAlertSound(1025)

        // アニメーション
        UIView.animate(withDuration: 2.0, animations: {
            // アルファ値を1.0に変化させる(初期値はStoryboardで0.0に設定済み)
            self.correctImageView.alpha = 1.0
        }) { (Bool) in
            self.goNextQuestion() // アニメーション完了後に次の問題に進む
        }
    }

    // 次の問題に不正解のアニメーション付きで遷移する
    func goNextQuestionWithIncorrectAnimation() {
        // 不正解を伝える音を鳴らす
        AudioServicesPlayAlertSound(1006)
        // アニメーション
        UIView.animate(withDuration: 2.0, animations: {
            // アルファ値を1.0に変化させる(初期値はStoryboardで0.0に設定済み)
            self.incorrectImageView.alpha = 1.0
        }) { (Bool) in
            self.goNextQuestion() // アニメーション完了後に次の問題に進む
        }
    }

    // 次の問題へ遷移する
    func goNextQuestion() {
        // 問題文の取り出し
        guard let nextQuestion =
            QuestionDataManager.sharedInstance.nextQuestion() else {
                // 問題文がなければ結果画面へ遷移する
                // StoryboardのIdentifierに設定した値(result)を指定して
                // ViewControllerを生成する
                if let resultViewController = storyboard?.instantiateViewController(withIdentifier: "result") as? ResultViewController {
                    // StoryboardのSegueを利用しない明示的な画面遷移処理
                    present(resultViewController, animated: true, completion: nil)
                }
                return
        }
        // 問題文がある場合は次の問題へ遷移する
        // StoryboardのIdentifierに設定した値(question)を設定して
        // ViewControllerを生成する
        if let nextQuestionViewController =
            storyboard?.instantiateViewController(withIdentifier: "question")
                as? QuestionViewController {
            nextQuestionViewController.questionData = nextQuestion
            // StoryboardのSegueを利用しない明示的な画面遷移処理
            present(nextQuestionViewController, animated: true,
                    completion: nil)
        }
    }
}

試したこと

・部品接続の確認
・コードの間違え探し

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

なし

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

0

viewDidLoadでは、questionDataはまだnilです。
全画面でquestionDataに対して情報を設定していると推測しますが、
QuestionViewControllerのインスタンスを作成した時点でviewDidLoadが呼ばれます。
viewWillAppear / viewDidAppear(画面表示する直前/直後に呼ばれる)であれば、questionDataが利用できるはずです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

そもそもquestionDataは前画面から渡しているのでしょうかね?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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