【Swift5/Xcode】入門編!クイズアプリを作成してみよう!参考書より丁寧に解説します。【Part5】

サトリク

この記事は、Pert5です。前編を読んでいない方は、上記の記事から読んでください。

今の状態

  • スタート画面でスタートを押すと、問題画面に遷移する
  • 問題画面で選択肢を押すと、コンソール上で正誤判定が行われ、次の画面問題がセットされる
  • 5問以上解くと、スコア画面に遷移する

サトリク

今の状況はざっとこんな感じだと思います!

Part5では、主にスコア画面を完成させましょう!

 

 

スコア画面でトップに戻るボタン実装

スコア画面の「トップに戻るボタン」を実装していきましょう!

STEP.1
Main.storyboardを表示

  (show the Project navigator)を選択

②Main.storyboardを選択

STEP.2
コード画面と2分割にする

①「トップに戻る」を選択

command + option + shift + enterMain.storyboardScoreViewController.swiftを2分割

STEP.3
ボタンを接続

controlを押しながら、18行目と19行目の間にドラッグ&ドロップ

①「Name」にtoTopBtnActionと入力

②「Connect」をクリック

STEP.4
トップに戻る処理

先ほどの接続で、以下のようなメソッドが追加されました。

@IBAction func toTopBtnAction(_ sender: Any) {
}

 

このメソッドは、「トップに戻るボタン」を押したときに呼ばれます。

このコードを以下のように書き換えてください。

@IBAction func toTopBtnAction(_ sender: Any) {
    self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}

 

この一行で、二つ前の画面に戻れます。

STEP.5
実行して確認

左上のボタンを押すか、command + rで実行してトップボタンでスタート画面に戻れることを確認しましょう。

完了

確認ができたら、次にいきましょう!

コンソールにスコアを表示させる

正解した点数を表示してみたいと思います。

STEP.1
QuizViewController.swiftを表示

  (show the Project navigator)を選択

QuizViewController.swiftを選択

STEP.2
正解数を入れる変数を用意

正解数を入れる変数を用意します。

24行目あたり(var quizTotal = 5の下)に以下の変数を宣言してください。

var correctCount = 0

 

このcorrectCountに正解したら点数を入れていきたいと思います。

STEP.3
正解したらcorrectCountに1点ずつ入れるプログラム

正解したら、correctCountに1点ずつ入れていきましょう。

40行目あたりのbtnActionメソッドを以下のように書き換えましょう。

@IBAction func btnAction(sender: UIButton) {
    if sender.tag == Int(quizArray[1]) {
        correctCount += 1
        print("正解")
    } else {
        print("不正解")
    }
    print("スコア:\(correctCount)")
    nextQuiz()
}

 

正解した場合、に、correctCountに1足していきます。

STEP.4
実行して確認

左上のボタンを押すか、command + rで実行してコンソールに、スコア:nと表示されることを確認しましょう!

完了
確認できたら完了です。次に進みましょう!

スコア画面でスコアを表示させる

先ほどコンソールに表示させたスコアをスコア画面に表示させましょう。

スコア画面でスコアを表示させる手順

  1. QuizViewController.swiftでcorrectCountにスコアを記録する
  2. 画面遷移と同時に、correctCountをスコア画面に渡す
  3. もらった値をlabelに代入する

 

STEP.1
ScoreViewController.swiftを表示

  (show the Project navigator)を選択

ScoreViewController.swiftを選択

STEP.2
変数を追加

まずは、受け取るための変数を作成します。

13行目あたりに(class ScoreViewController: UIViewController {の下)に以下の変数を宣言します。

var correct = 0

 

STEP.3
QuizViewController.swiftを表示

  (show the Project navigator)を選択

QuizViewController.swiftを選択

STEP.4
prepareメソッド追加

次に、画面遷移する際に、値を渡すための準備をします。

39行目あたり(}の下)に以下のメソッドを追加してください。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let sVC = segue.destination as! ScoreViewController
    sVC.correct = correctCount
}

 

これで、画面遷移時に、

ScoreViewControllerの変数correctに、QuizViewControllercorrectCountを代入します。

STEP.5
Main.storyboardを表示

  (show the Project navigator)を選択

②Main.storyboardを選択

STEP.6
Labelの幅を広げる

①Labelを選択

② (Show the Attributes inspector)を選択

②Alignmentを中央揃え

STEP.7
コード画面と2分割にする

①Labelを選択

command + option + shift + enterMain.storyboardScoreViewController.swiftを2分割

STEP.8
Labelを紐付ける

controlを押しながら、11行目と12行目の間にドラッグ&ドロップ

①「Name」にscoreLabel

②「Connect」をクリック

STEP.8
scoreLabelにテキストを代入

16行目あたりのviewDidLoadメソッドを以下のように書き換えましょう。

override func viewDidLoad() {
    super.viewDidLoad()
    scoreLabel.text = "\(correct)問正解!"
    // Do any additional setup after loading the view.
}

 

STEP.8
実行して確認

左上のボタンを押すか、command + rで実行して◯問正解!と表示されるか確認しましょう!

このように正解数が表示されるはずです。

完了

これで、スコア画面の実装はある程度終わりました!

ここまでの全コード

注意

コメントは削除しているので、今後の講座で行がずれてしまう可能性があります。

QuizViewController

import UIKit

class QuizViewController: UIViewController {

    @IBOutlet weak var quizNumberLabel: UILabel!
    @IBOutlet weak var quizTextView: UITextView!
    @IBOutlet weak var answerBtn1: UIButton!
    @IBOutlet weak var answerBtn2: UIButton!
    @IBOutlet weak var answerBtn3: UIButton!
    @IBOutlet weak var answerBtn4: UIButton!

    var csvArray: [String] = []
    var quizArray: [String] = []
    var quizCount = 0
    var quizTotal = 5
    var correctCount = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        csvArray = loadCSV(fileName: "quiz")
        print(csvArray)
        quizArray = csvArray[quizCount].components(separatedBy: ",")
        quizNumberLabel.text = "第\(quizCount + 1)問"
        quizTextView.text = quizArray[0]
        answerBtn1.setTitle(quizArray[2], for: .normal)
        answerBtn2.setTitle(quizArray[3], for: .normal)
        answerBtn3.setTitle(quizArray[4], for: .normal)
        answerBtn4.setTitle(quizArray[5], for: .normal)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let sVC = segue.destination as! ScoreViewController
        sVC.correct = correctCount
    }

    @IBAction func btnAction(sender: UIButton) {
        if sender.tag == Int(quizArray[1]) {
            correctCount += 1
            print("正解")
        } else {
            print("不正解")
        }
        print("スコア:\(correctCount)")
        nextQuiz()
    }

    func nextQuiz() {
        quizCount += 1
        quizArray.removeAll()
        if quizCount < quizTotal {
            quizArray = csvArray[quizCount].components(separatedBy: ",")
            quizNumberLabel.text = "第\(quizCount + 1)問"
            quizTextView.text = quizArray[0]
            answerBtn1.setTitle(quizArray[2], for: .normal)
            answerBtn2.setTitle(quizArray[3], for: .normal)
            answerBtn3.setTitle(quizArray[4], for: .normal)
            answerBtn4.setTitle(quizArray[5], for: .normal)
        } else {
            performSegue(withIdentifier: "score", sender: nil)
        }
    }

    func loadCSV(fileName: String) -> [String] {
        let csvBundle = Bundle.main.path(forResource: fileName, ofType: "csv")!
        do {
            let csvData = try String(contentsOfFile: csvBundle,encoding: String.Encoding.utf8)
            let lineChange = csvData.replacingOccurrences(of: "\r", with: "\n")
            csvArray = lineChange.components(separatedBy: "\n")
        } catch {
            print("エラー")
        }
        return csvArray
    }
}

ScoreViewController

import UIKit

class ScoreViewController: UIViewController {
    @IBOutlet weak var scoreLabel: UILabel!

    var correct = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        scoreLabel.text = "\(correct)問正解!"
    }
    
    @IBAction func toTopBtnAction(_ sender: Any) {
        self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
    }
}

クイズアプリを作ろうPert5まとめ

 

まとめ
  • self.dismiss(animated: true, completion: nil)で画面遷移元に戻る
  • prepareメソッドで、画面遷移時に値を渡せる