먼저, 구조체 내부에서의 immutability에 대해 정리했다.
https://dmsitter.tistory.com/115
QuizBrain.swift의 struct 내부에 있는 두 함수(메소드)를 비교해보면,
getProgress()는 property의 값을 변화시키지 않지만
nextQuestion()은 property(questionNumber)의 값을 변화시킨다.
기본적으로 struct의 property는 self로, 내부에서 값을 변화시킬 수 없기 때문에
immutability에 대해서 정리했던 글에 작성해둔 것처럼
mutating으로 마킹해줘야 한다.
'mutating'만 붙여주면,
기존에 MVC design pattern을 사용하지 않았을 때와 동일하게 어플이 만들어진 것을 테스트해볼 수 있다.
Challenge )
왼쪽 상단에 User score가 출력되도록 만들어볼 것, 마지막 문제가 끝나면 점수는 0으로 초기화시킬 것
1. main.storyboard에서 label을 추가
2. IBOutlet 연결 - 'scoreLabel'
3. updateUI() 코드블럭에
scoreLabel.text = "Score : \(quizBrain.getScore())" 코드 추가
이후
메소드 부분을 위와 같이 수정하여 어플을 완성했다.
Challenge )
3가지 선택지가 있는 quizzler 만들기
import Foundation
struct Question {
let text : String
let answer : [String]
let correctAnswer : String
init(q : String, a : [String], correctAnswer : String) {
text = q
answer = a
self.correctAnswer = correctAnswer
}
}
Question.swift
import Foundation
struct QuizBrain {
let quiz = [
Question(q: "Which is the largest organ in the human body?", a: ["Heart", "Skin", "Large Intestine"], correctAnswer: "Skin"),
Question(q: "Five dollars is worth how many nickels?", a: ["25", "50", "100"], correctAnswer: "100"),
Question(q: "What do the letters in the GMT time zone stand for?", a: ["Global Meridian Time", "Greenwich Mean Time", "General Median Time"], correctAnswer: "Greenwich Mean Time"),
Question(q: "What is the French word for 'hat'?", a: ["Chapeau", "Écharpe", "Bonnet"], correctAnswer: "Chapeau"),
Question(q: "In past times, what would a gentleman keep in his fob pocket?", a: ["Notebook", "Handkerchief", "Watch"], correctAnswer: "Watch"),
Question(q: "How would one say goodbye in Spanish?", a: ["Au Revoir", "Adiós", "Salir"], correctAnswer: "Adiós"),
Question(q: "Which of these colours is NOT featured in the logo for Google?", a: ["Green", "Orange", "Blue"], correctAnswer: "Orange"),
Question(q: "What alcoholic drink is made from molasses?", a: ["Rum", "Whisky", "Gin"], correctAnswer: "Rum"),
Question(q: "What type of animal was Harambe?", a: ["Panda", "Gorilla", "Crocodile"], correctAnswer: "Gorilla"),
Question(q: "Where is Tasmania located?", a: ["Indonesia", "Australia", "Scotland"], correctAnswer: "Australia")
]
var questionNumber = 0
var quizScore = 0
//아랫줄에서 answer은 external parameter, 함수 외부에서 사용할 수 있음
//userAnswer는 internal parameter, 이 함수 안에서 사용할 수 있음
//만약 external parameter name을 사용하지 않을거라면 '_'으로 대신하면 된다.
//func checkAnswer(_ userAnswer: String)와 동일
mutating func checkAnswer(correctAnswer userAnswer: String) -> Bool {
if userAnswer == quiz[questionNumber].correctAnswer {
//user got it right
quizScore += 1
return true
} else {
//user got it wrong
return false
}
}
func getQuestionText() -> String {
return quiz[questionNumber].text
}
func getAnswerSheet(buttonNumber : Int) -> String{
if buttonNumber == 0 {
return quiz[questionNumber].answer[0]
} else if buttonNumber == 1 {
return quiz[questionNumber].answer[1]
} else {
return quiz[questionNumber].answer[2]
}
}
func getProgress() -> Float {
return Float(questionNumber + 1) / Float(quiz.count)
}
mutating func nextQuestion() {
if questionNumber < quiz.count - 1 {
questionNumber += 1
} else {
quizScore = 0
questionNumber = 0
}
}
func getScore() -> Int {
return quizScore
}
}
QuizBrain.swift
//
// ViewController.swift
// Quizzler-iOS13
//
// Created by Angela Yu on 12/07/2019.
// Copyright © 2019 The App Brewery. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var questionLabel: UILabel!
@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet weak var firstButton: UIButton!
@IBOutlet weak var secondButton: UIButton!
@IBOutlet weak var thirdButton: UIButton!
@IBOutlet weak var scoreLabel: UILabel!
var quizBrain = QuizBrain()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
updateUI()
}
@IBAction func answerButtonPressed(_ sender: UIButton) {
let userAnswer = sender.currentTitle!
//QuizBrain.swift에서 external parameter name을 _로 입력한 경우
//quizBrain.checkAnswer(userAnswer) 아래와 동일
let userGotItRight = quizBrain.checkAnswer(correctAnswer: userAnswer)
//QuizBrain.swift에서 external parameter name을 answer로 입력한 경우
if userGotItRight {
// UIcolor == 미리 build되어 있는 color
sender.backgroundColor = UIColor.green
} else {
sender.backgroundColor = UIColor.red
}
quizBrain.nextQuestion()
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
}
@objc func updateUI() {
questionLabel.text = quizBrain.getQuestionText()
firstButton.setTitle(quizBrain.getAnswerSheet(buttonNumber: 0), for: .normal)
secondButton.setTitle(quizBrain.getAnswerSheet(buttonNumber: 1), for: .normal)
thirdButton.setTitle(quizBrain.getAnswerSheet(buttonNumber: 2), for: .normal)
progressBar.progress = quizBrain.getProgress()
firstButton.backgroundColor = UIColor.clear
secondButton.backgroundColor = UIColor.clear
thirdButton.backgroundColor = UIColor.clear
//questionNumber가 0부터 시작하기 때문에, 첫 Q일 때도 progressBar가 진행되도록 하기 위해 questionNumber + 1 사용함
scoreLabel.text = "Score : \(quizBrain.getScore())"
}
}
viewController.swift
완성!
'Today I Learned' 카테고리의 다른 글
20210711 Destiny project -2 (0) | 2021.07.12 |
---|---|
20210706 Destiny project -1 (0) | 2021.07.06 |
20210628 Quizzler project - 4 (with MVC design pattern) (0) | 2021.06.29 |
20210627 Quizzler project -3 (0) | 2021.06.27 |
20210623 Quizzler project -2 (0) | 2021.06.24 |