選擇題 App

圖片來源:Photo by Kristopher Roller on Unsplash

Demo :

一開始先建立一個問題的類別,確認題目裡會有哪些項目(問題描述、答案、圖片名稱、四種選項)

////  Questions.swift//  MultipleChoice
import
Foundation
class Questions {var description: String = ""var imageName: String = ""var allOption: [String] = []var answer: String = ""}

接著設置所有問題的內容

let descriptionList = ["請問下圖代表什麼星座?", "請問下列哪個不屬於水象星座?", "月球上的一天,是地球的幾天呢?", "在希臘神話中,愛神維納斯是下列哪個星座的守護神?" , "請問獅子座的守護神是誰?" , "請問在5月28日出生的人代表什麼星座?" , "北斗七星位於哪個星座上?" , "請問何者為下圖的星系?" , "請問在幾月份會有雙子座流星雨?" , "下列哪一個不是行星?" , "以下符號代表什麼星座?" , "請問摩羯座的英文為何?" , "請問最顧家的星座為何?" , "請問英文單字中Aquarius代表什麼星座?" , "太陽系中密度最大的行星是什麼?" , "地球上第一個登陸月球的太空人是誰?" , "請問射手座還可以稱作為什麼?" , "請問古希臘神話中的眾神之王是誰?" , "請問天秤座的守護星為下列何者?", "希臘神話中的蛇髮魔女為下列何人?"]let answerList = ["雙子座", "水瓶座", "約一個月", "金牛座", "太陽神阿波羅" , "雙子座" , "大熊座" , "仙女座星系" , "12" , "太陽" , "處女座" , "Capricorn" , "巨蟹座" , "水瓶座" , "地球" , "阿姆斯壯" , "人馬座" , "宙斯" , "金星" , "梅杜莎"]let imageNameList = ["雙子座", "", "", "" , "" , "" , "" , "仙女座星系" , "" , "" , "處女座" , "" , "" , "" , "" , "" , "" , "" , "" , ""]var optionList = [["雙子座","天秤座", "水瓶座", "摩羯座"],["巨蟹座","雙魚座", "水瓶座", "天蠍座"] ,["約一天","約一週", "約一個月", "約一年"] ,["摩羯座","牡羊座", "獅子座", "金牛座"] ,["太陽神阿波羅","海神涅普頓", "愛神丘比特", "地獄之神普爾德"] ,["巨蟹座","金牛座", "雙子座", "牡羊座"] ,["仙王座","天鵝座", "大熊座", "天龍座"] ,["仙女座星系","波德星系", "風車星系", "向日葵星系"] ,["11","5", "7", "12"] ,["太陽","火星", "地球", "木星"] ,["金牛座","處女座", "射手座", "水瓶座"],["Capricorn","Gemini", "Aries", "Scorpio"] ,["巨蟹座","牡羊座", "獅子座", "水瓶座"] ,["水瓶座","天蠍座", "射手座", "雙魚座"]  ,["天王星","木星", "地球", "火星"] ,["艾德林","阿姆斯壯", "柯林斯", "川普"] ,["劍魚座","人馬座", "小熊座", "鹿豹座"] ,["宙斯","阿波羅", "海克力斯", "塞勒涅"] ,["水星","金星", "太陽", "天王星"] ,["梅杜莎","維納斯", "忒彌絲", "狄俄涅"]]

當每一次開始的時候才加入題目,也可以選擇在viewDidLoad裡面加入,但因為想要每次題目裡的四顆按鈕順序都不一樣,所以只要重新開始都會再做一遍,且把放置題目的陣列、分數、當前的題號都恢復為預設值。

因為在一開始跟點選下一題的時候都需要顯示題目所以寫成一個func就不必重覆寫(showQuestion())

// MARK: - IBAction@IBAction func didTapStartButton(_ sender: UIButton) {// 把題目陣列預設為空,重新塞題目進去self.questions = []self.nowQuestions = []// 每一次開始都重新寫入題目for i in 0..<descriptionList.count {let question = Questions()question.description = self.descriptionList[i]question.imageName = self.imageNameList[i]question.answer = self.answerList[i]// 調整四個選項的順序self.optionList[i].shuffle()question.allOption = self.optionList[i]questions.append(question)}// 調整題目的順序self.questions.shuffle()// 選擇此次題目for i in 0..<questionQuantity {self.nowQuestions.append(self.questions[i])}self.score = 0self.scoreLabel.text = "\(self.score)"self.currentIndex = 0self.startView.isHidden = trueself.nextButton.isHidden = falseself.showQuestion()}

在選擇下一題的時候,先判斷在這題是不是已經作答,如果還沒就是跳出系統的預設視窗告知需要先選擇才可以繼續進行,如果已經作答了接著判斷是不是為最後一題,如果是就不再顯示下一題的按鈕

@IBAction func didTapNextButton(_ sender: UIButton) {    // 確認完成此題    if self.isFinished {        if self.currentIndex == self.questionQuantity - 1               self.nextButton.isHidden = true

}else {
self.currentIndex += 1 print(self.currentIndex)
}
self.showQuestion() }else { let alert = UIAlertController(title: "", message: "請選擇任一答案,再前往下一題", preferredStyle: .alert) let action = UIAlertAction(title: "確定", style: .default) alert.addAction(action) self.show(alert, sender: nil)
}
}

回答問題的部分,先判斷了哪個選項正確的答案,在一開始選項宣告為一組陣列,這時候可以透過元件的tag屬性來區別,每個tag都需要設置不一樣的數值(ex: 四個不同的選項,從0~3的順序設置)

@IBOutlet var optionButtonList: [UIButton]!@IBOutlet var statusImageViewList: [UIImageView]!

其中紀錄最高分的地方,利用了UserDefaults來儲存最高紀錄,UserDefaults可以用來儲存APP內簡易的資料,這邊利用它可一直將最高的分數保存在手機內,除非移除APP重新安裝,或者寫刪除的語法才會不見

UserDefaults.standard.removeObject(forKey: Object)

@IBAction func didTapButton(_ sender: UIButton) {   // 選擇的答案
let selectAnswer = sender.titleLabel?.text
// 正確答案
let correctAnswer = self.nowQuestions[self.currentIndex].answer
// 正確答案的Index
var correctNumber = -1

// 完成作答
self.isFinished = true
// 判斷對還是錯
var isCorrect = false

for
button in self.optionButtonList {
// 把button狀態改為不能點選
button.isEnabled = false
//判斷哪個選項是正確答案
if button.titleLabel!.text == correctAnswer {
correctNumber = button.tag
}
}
// 判斷所選擇項目是否為正確答案 if selectAnswer == correctAnswer { isCorrect = true

self
.score += 10
self.scoreLabel.text = "\(self.score)"
}

// 在自己選擇的項目 & 正確答案 中添加是否正確的圖片
for statusImageView in self.statusImageViewList {

if statusImageView.tag == correctNumber {

statusImageView.image = UIImage(named: "icon_v")
}
if statusImageView.tag == sender.tag { if !isCorrect { statusImageView.image = UIImage(named: "icon_x")
}
}
}

// 判斷是否為最後一題
if self.currentIndex == self.questionQuantity - 1 {
var best = 0 if UserDefaults.standard.object(forKey: "BEST") != nil { best = UserDefaults.standard.object(forKey: "BEST") as! Int
}
var alert = UIAlertController()

if best > 0 {

// 判斷此次得分有沒有比最高紀錄多,並儲存最高的分數在手機
if best > self.score { alert = UIAlertController(title: "上次最高紀錄: \(best) \n 這回合總分:\(score) ", message: "", preferredStyle: .alert) UserDefaults.standard.set(best, forKey: "BEST")
UserDefaults.standard.synchronize()
}else { alert = UIAlertController(title: "上次最高紀錄: \(best) \n 這回合總分:\(score) \n 恭喜你!成為最高紀錄者! ", message: "", preferredStyle: .alert) UserDefaults.standard.set(self.score, forKey: "BEST")
UserDefaults.standard.synchronize()
} }else { alert = UIAlertController(title: "這回合總分:\(score)", message: "", preferredStyle: .alert)
// 儲存最高的分數在手機
UserDefaults.standard.set(self.score, forKey: "BEST")
UserDefaults.standard.synchronize()
} let action = UIAlertAction(title: "再試一次", style: .default) { (_) in
// 顯示開始的頁面
self.startView.isHidden = false
} alert.addAction(action) self.show(alert, sender: nil) }}

GitHub :

參考資料:

--

--