サトリク
前回の講座を受けていない方はこちらから
今の状態
サトリク
今の状況としては、
- スタート画面でスタートを押すと、問題画面に遷移する
- 問題画面で選択肢を押すと、コンソール上で正誤判定が行われ、次の画面問題がセットされる
- 問題全て解くと、スコア画面に遷移する
ざっとこんな感じだと思います!

Part5では、主にスコア画面を完成させましょう!
スコア画面に正解数を表示し、トップに戻るボタンで、トップに戻るようにしましょう。
![]()
スコア画面でトップに戻るボタン実装
まずは、スコア画面でトップに戻るボタンを押したらトップに戻るようにしましょう。

左のメニューからMain.storyboardを選択してください。
オブジェクトを紐づけるために、スコア画面とスコア画面のプログラムファイルを2分割で表示させましょう。

①スコア画面の上のバーをクリック
②command + option + control + enterで2分割
「トップに戻る」ボタンをコードと紐付けましょう。

controlを押しながら、override func viewDidLoad() {のブロックの外にドラッグ&ドロップ

NameにtoTopButtonActionと入力し、Connect

左のメニューからScoreViewController.swiftを選択しましょう。
先程接続してできた、ボタンを押したら呼ばれるブロックに以下のコードを記述しましょう。
@IBAction func toTopButtonAction(_ sender: Any) {
self.presentingViewController?.presentingViewController?.dismiss(animated: true)
}

この1行は2つ前の画面に戻るという処理です。
左上の再生ボタンを押して、実行して確認しましょう。

クイズを行い、トップに戻るを押したら、このようにトップに戻れたら成功です!
これでトップ画面に戻る処理ができました。
スコアをカウントしてコンソールに表示させる
次は、正解した数を数えてコンソールに表示させていきたいと思います。

左のメニューからQuizViewController.swiftを選択してください。
var quizCount = 0の下に以下のコードを記述してください。
var correctCount = 0

正解したら、この値に1プラスしていきます。
correctCountに1プラスするボタンを押したときに呼ばれるブロックを以下のように書き換えましょう。
@IBAction func btnAction(sender: UIButton) {
if sender.tag == Int(quizArray[1]) {
correctCount += 1
print("正解")
} else {
print("不正解")
}
print("スコア:\(correctCount)")
nextQuiz()
}

正解したら、correctCountに1プラスしています。
そして、正誤判定が終わったら、コンソールに現在のスコアを表示しています。
実行して問題を解いてみましょう。
おそらく、コンソールにスコアが表示されるはずです。

次は、このスコアをスコア画面に表示しましょう。
が、しかしcorrectCountは、QuizViewController.swiftの中にあるので、スコア画面では使えません。
なので、まず、スコア画面にcorrectCountを渡す処理を書いていきましょう。
スコア画面に値を渡してスコアを表示させる

左のメニューからScoreViewController.swiftを選択
まずは、ScoreViewController.swiftで受け取る箱を用意します。
Classの下に以下のコードを記述しましょう。
var correct = 0

この箱にQuizViewController.swiftのcorrectCountを遷移するときに代入したいと思います。

左のメニューからQuizViewController.swiftを選択してください。
画面遷移するときに、値を渡すコードを記述します。
viewDidLoad()ブロックの下に以下のコードを記述してください。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let scoreVC = segue.destination as! ScoreViewController
scoreVC.correct = correctCount
}

これで、スコア画面で正解した数を取得できるようになったので、あとはLabelに表示させるだけです。

左のメニューからMain.storyboardを選択してください。
枠が狭すぎて文字が…にならないように枠を広げておきましょう。

①Labelの枠を広げる
②
(Show the Attributes inspector)を選択
③Alignmentを中央揃えに変更

①スコア画面の上のバーを選択
②command + option + control + enterで2分割

controlを押しながら、labelをclassの下にドラッグ&ドロップしましょう。

NameにscoreLabelと入力し、Connect

左のメニューからScoreViewController.swiftを選択
QuizViewController.swiftから受け取った値を先程紐付けたscoreLabelに代入します。
viewDidLoad()に以下の1行を記述してください。
scoreLabel.text = "\(correct)問正解!"


このように、問題が終わると「◯問正解!」と表示されるはずです!
これでスコア画面が一通りできました!
ここまでの全コード
QuizViewController
import UIKit
class QuizViewController: UIViewController {
@IBOutlet var quizNumberLabel: UILabel!
@IBOutlet var quizTextView: UITextView!
@IBOutlet var answerButton1: UIButton!
@IBOutlet var answerButton2: UIButton!
@IBOutlet var answerButton3: UIButton!
@IBOutlet var answerButton4: UIButton!
var csvArray: [String] = []
var quizArray: [String] = []
var quizCount = 0
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]
answerButton1.setTitle(quizArray[2], for: .normal)
answerButton2.setTitle(quizArray[3], for: .normal)
answerButton3.setTitle(quizArray[4], for: .normal)
answerButton4.setTitle(quizArray[5], for: .normal)
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let scoreVC = segue.destination as! ScoreViewController
scoreVC.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
if quizCount < csvArray.count {
quizArray = csvArray[quizCount].components(separatedBy: ",")
quizNumberLabel.text = "第\(quizCount + 1)問"
quizTextView.text = quizArray[0]
answerButton1.setTitle(quizArray[2], for: .normal)
answerButton2.setTitle(quizArray[3], for: .normal)
answerButton3.setTitle(quizArray[4], for: .normal)
answerButton4.setTitle(quizArray[5], for: .normal)
} else {
performSegue(withIdentifier: "toScoreVC", 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")
csvArray.removeLast()
} catch {
print("エラー")
}
return csvArray
}
/*
// 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.destination.
// Pass the selected object to the new view controller.
}
*/
}
ScoreViewController
import UIKit
class ScoreViewController: UIViewController {
@IBOutlet var scoreLabel: UILabel!
var correct = 0
override func viewDidLoad() {
super.viewDidLoad()
scoreLabel.text = "\(correct)問正解!"
// Do any additional setup after loading the view.
}
@IBAction func toTopButtonAction(_ sender: Any) {
self.presentingViewController?.presentingViewController?.dismiss(animated: true)
}
/*
// 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.destination.
// Pass the selected object to the new view controller.
}
*/
}
クイズアプリを作ろうPert5まとめ
self.presentingViewController?.presentingViewController?.dismiss(animated: true)で2つ前の画面に戻る- prepareメソッドで、画面遷移時に値を渡せる
一緒に楽しく雑談しながらアプリ開発しませんか?

RikutoSato
satorikublogの筆者がアプリ開発をマンツーマンでサポートします。
あなたのクイズアプリをAppStoreにリリースするまで、チャットや、ビデオ通話で楽しく雑談でもしながらサポートします。エラーで先に進まない方や、アイデアはあるけど、そのアイデアをアプリに実現できない方など、気軽にご相談ください!
次の講座(Pert6)
本で勉強したい方にはこちら


