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

サトリク

前回の講座を受けていない方はこちらから

 

今の状態

サトリク

今の状態は、スタートボタンを押すと、問題画面に遷移し、Buttonを押すとコンソールに押したボタンの番号が表示される。という状態です。

今回は、このLabelに問題数、Text Viewに問題、Buttonに選択肢を表示していきたいと思います。

では早速クイズアプリPart3をやっていきましょう!

 

 

問題データ(CSVファイル)作成

サトリク

まずは問題を作成します。

今回のクイズアプリでは、問題のデータはCSVファイル(カンマ区切りのファイル)で作ります。

CSVファイルとは?

CSVとは「Comma Separated Valueカンマ セパレーテッド バリュー」の略で、,(カンマ)で区切られた(セパレーテッド)値(バリュー)ということです。

今回作る問題データは、問題文、正解番号、選択肢1、選択肢2、選択肢3、選択肢4を入れていきたいと思います。

つまり、こんな感じのファイルを作成します。

問題文,正解番号,選択肢1,選択肢2,選択肢3,選択肢4
問題文,正解番号,選択肢1,選択肢2,選択肢3,選択肢4
問題文,正解番号,選択肢1,選択肢2,選択肢3,選択肢4
問題文,正解番号,選択肢1,選択肢2,選択肢3,選択肢4
問題文,正解番号,選択肢1,選択肢2,選択肢3,選択肢4

 

STEP.1
ファイル作成

command + nでファイル作成ウィンドウを表示

①下の方にある「Empty」を選択

②「Next」をクリック

STEP.2
ファイル名、保存先選択

①「Save As:」にquiz.csvと入力

②「Create」をクリック

STEP.3
問題データをcsvファイルに入力

書き方は、問題文,正解番号,選択肢1,選択肢2,選択肢3,選択肢4です。

最低5問用意しましょう。

 

注意!

正解番号は「選択肢1なら0」「選択肢2なら1」「選択肢3なら2」「選択肢4なら3」です。

少しややこしいですが、間違えないようにしましょう。

 

サトリク

自分で問題を作成してもいいですが、問題を考えるのがめんどくさいという方のためにしょうもないクイズを用意しました。

こちらをコピペしてください。

 

ぼうしの中に入っている動物はなに?,3,かめ,ウサギ,キリン,うし
飲むとおこられるジュースってなに?,0,コーラ,サイダー,オレンジ,ピーチ
おいしくて甘い てら ってどんなてら?,2,リンゴ,かき,カステラ,ホットケーキ
いつも文句ばかり言っている動物はなに?,3,いのしし,ぞう,さい,うし
とってもつめたい いす ってなに?,1,こおり,アイス,ふぶき,れいぞうこ

 

こんな感じになれば、OKです。

完了

これで問題データ作成は完了です。

CSVファイルを読み込むプログラムを作成

先ほど作成した問題データを取り込むプログラムを作成しましょう。

ここでは、超初心者の方はそこまで内容は理解しなくてもいいです。僕も最初は全くわかりませんでした。こういうもんなんだなぁ程度でやりましょう。

STEP.1
QuizViewControllerを開く

左側のメニューから、QuizViewController.swiftをダブルクリックする

STEP.2
csvファイルを格納する配列宣言

19行目あたり、IBOutlet weak varoverride func viewDidLoad()の間に以下コードを記述してください。

 

var csvArray: [String] = []

ここでは、配列を宣言しています。配列というのは複数の要素(値)を入れる箱だと思ってください。

一旦この箱に先ほど作った問題のデータ(csvファイル)を入れていきたいと思います。

STEP.3
配列(csvArray)ににデータをいれる

32行目あたり、}/*の間に以下のコードを記述してください。

 

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
}

ここの処理は、一旦csvファイルから全てのデータを取得して、カンマで区切られたデータを一つ一つ取り出すという処理です。
まぁ簡単にいうと、ここでcsvファイルを読み込んでます。

STEP.4
関数を呼び出す処理

24行目あたり(super.viewDidLoad()の下)に以下のコードを記述してください。

 

csvArray = loadCSV(fileName: "quiz")
print(csvArray)

ここでは、先ほど読み込んだcsvファイルをcsvArrayというSTEP.2で作った箱に移し替えてます。

基本的なことですが、print(csvArray)というのは、コンソール上(Xcodeの右下)にcsvArrayの情報を表示するという処理です。実際にアプリの機能とは関係なく自分たちが確認するための記述です。今回で言うと、csvファイルから取ってきたデータを確認するために書いています。

STEP.5
実行して確認する

左上の再生ボタンか、command + rで実行して確認してみましょう。

実行してスタートボタンを押した瞬間に、コンソール(Xcodeの右下)に問題デーうまく行っていれば、タが表示されるはずです。

完了

サトリク

上記のように確認できたら完了です!

 

問題文と選択肢を表示するプログラムを作成

次は、問題データの問題文や選択肢を、画面上に表示させるプログラムを書いていきたいと思います。

記述するファイルは、先ほどと同じくQuizViewController.swiftです。

STEP.1
csvファイルから取り出した問題を格納する配列・変数宣言

20行目あたり、var csvArray: [String] = []の下に以下のコードを記述してください。

 

var quizArray: [String] = []
var quizCount = 0

2つの箱を用意します。

  • quizArrayは、問題データの1問ずつデータをいれる箱
  • quizCountは、現在の問題数を表示するための箱
STEP.2
問題を表示させる

29行目あたり(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)

 

ふりがなプログラミングで簡単に解説

一行目は、問題のデータの一番最初の行を取ってくる処理です。

quizArray1問目を入れる箱 =代入 csvArray[quizCountcsvデータのquizCount番目の行].components(separatedBy: “,”)カンマ区切りで分割

 

二行目は、問題数を表示する処理です。

quizNumberLabel紐付けた問題番号.textのテキスト =代入 “第\(quizCount + 1)問”第○問

 

三行目は、問題文を表示を表示する処理です。

quizTextVie問題文w.textのテキスト =代入 quizArray[0]1問目のクイズの0番目の要素

 

四行目以降は、選択肢を表示する処理です。

answerBtn一つ目の解答ボタン1.setTitleの文字をセット(quizArray[2]1問目のクイズの2番目の要素, for: .normal通常のUIとして)

STEP.3
実行して確認する

左上の再生ボタンかcommand + rで実行して確認してみましょう。

このように、問題数、問題文、選択肢1、選択肢2、選択肢3、選択肢4が表示されていれば成功です。

注意

今回のアプリでは、iPhone11向けに作成しているので、iPhone11以外のシミュレーターで起動すると、レイアウトが崩れる場合があります。

後々のパートで修正するかも。。

完了

上記のことが確認できたら、このPart3は成功です。

次のPart4にいきましょう!

 

ここまでの全コード

注意

丸々コピペしても、エラーが出る場合は、もう一度Part1からやり直した方がいいかもしれません。

Xcodeになれていない状態で、修正するのはかなり至難の技です。

//
//  QuizViewController.swift
//  SampleQuiz
//
//  Created by RikutoSato on 2020/10/22.
//

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
    
    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)

        // Do any additional setup after loading the view.
    }
    
    @IBAction func btnAction(sender: UIButton) {
        //ボタンを押したときに呼ばれる
        print(sender.tag)
    }
    
    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
    }
    

    /*
    // 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.
    }
    */

}

 

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

 

まとめ
  • CSVファイルとは、,(カンマ)で区切られた(セパレーテッド)値(バリュー)のファイルのこと
  • var array: [String] = []で配列の宣言
  • var quizCount = 0で変数の宣言
  • label.text = "文字"でstoryboardと紐づいているlabelに文字を入れる
  • textView.text = "文字列"でstoryboardと紐づいているtextViewに文字を入れる
  • button.setTitle("文字列", for: .normal)でstoryboardと紐づいているButtonのタイトルに文字を入れる

 

一緒に楽しく雑談しながらアプリ開発しませんか?

RikutoSato

satorikublogの筆者がアプリ開発をマンツーマンでサポートします。

あなたのクイズアプリをAppStoreにリリースするまで、チャットや、ビデオ通話で楽しく雑談でもしながらサポートします。エラーで先に進まない方や、アイデアはあるけど、そのアイデアをアプリに実現できない方など、気軽にご相談ください!

詳しくはこちら