Screen in question I am trying to call the viewDidLoad()
func here with the question()
func a set number of times and only then call the code for the new view controller to be pushed. But, the code for both is getting executed at the same exact time such that as soon as the first round finishes, the view controller is pushed. I have tried using loops in different variations, but those attempts all led to similar results. Ideas? And thanks in advance!
var num1 = Int()
var num2 = Int()
var userInput = 0
@IBAction func numbers(_ sender: UIButton) {
answerLabel.text = answerLabel.text! + String(sender.tag - 1)
userInput = Int(answerLabel.text!)!
answer()
}
override func viewDidLoad() {
super.viewDidLoad()
// Views configuration
question()
}
func answer() {
let answer = num1 + num2
if userInput == answer {
answerLabel.text = ""
viewDidLoad()
let scoreVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ScoreViewController") as! ScoreViewController
self.navigationController?.pushViewController(scoreVC, animated: true)
}
}
func question() {
num1 = Int(arc4random_uniform(100))
num2 = Int(arc4random_uniform(100))
questionLabel.text = "\(num1) + \(num2)"
}
There are quit e few things that we can improve here. I'll start at basic. As these numbers are unset at the beginning we don't have to assign them yet. So instead of settings them to a default value we can leave them as Optionals which allows us to just define the type and leave them be for an assignment later on.
var num1: Int?
var num2: Int?
Now we wanna show a Question. The thing is, the viewDidLoad
shall only be used when - as the name suggests - the view loads. Because of this we simply create a Method and move our logic there. You already did that, I just renamed your function to a more speaking name
viewDidLoad() {
showNewQuestion()
}
showNewQuestion() { // previously question()
num1 = Int(arc4random_uniform(100))
num2 = Int(arc4random_uniform(100))
questionLabel.text = "\(num1) + \(num2)"
}
So far so good. Now we gotta check the input against the random value in the Button send function. Instead of force unwrapping (!
) it is better practise to safely unwrap (?
).
@IBAction func numbers(_ sender: UIButton) {
guard let userInput = answerLabel.text, let userInputAsInt = Int(userInput) else {
return
}
checkAnswer(userInput: userInputAsInt) // previously answere()
}
Lastly we improve your answer()
function. The thing you left is to count how many questions have been answered. If we don't ever check that how should the program know when to show the score? To fix this problem we remember how many questions were asked (correctAnsweres
) and we define a threshold when to show the score (showScoreAfter
)
var correctAnsweres = 0
var showScoreAfter = 5
func checkAnswer(userInputAsInt: Int) {
let answer = num1 + num2
if userInputAsInt != answers { // early exit if answered wrong
return
}
correctAnsweres += 1
answerLabel.text = ""
//either show score
if correctAnsweres % ShowScoreAfter == 0 {
let scoreVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ScoreViewController") as! ScoreViewController
self.navigationController?.pushViewController(scoreVC, animated: true)
}
// or new Question
else {
showNewQuestion()
}
}