*Xcode Project Entry* Letters in Words - Part 4
*This entry was actually typed yesterday on 30th November - I just never actually published it!
So yesterday was productive but so frustrating! I had dreams about getting a 60 second timer to work! Here is where we are at with the app.

Before I start, I'm going to 'tidy up' a bit. Get things organised into a proper MVC. It's all a bit too scattergun at the moment. So I will have subfolders then separate project files. If that doesn't work then I'll just focus down on what is exactly required!
Start Time - 8:59
*Only have a short amount of time until Cath's Dad comes over. So just a bit of sorting first!
OK it doesn't just work to create a new Swift file to put values into. Nope that will not work!
*Just going to check how this worked with Angela's Quizzler app as mine doesn't have all of the info.
*Right various delays. The reason it does not work is because you need a class/struct to have the data model.
YES!!! IT worked!!
So yesterday was productive but so frustrating! I had dreams about getting a 60 second timer to work! Here is where we are at with the app.

Before I start, I'm going to 'tidy up' a bit. Get things organised into a proper MVC. It's all a bit too scattergun at the moment. So I will have subfolders then separate project files. If that doesn't work then I'll just focus down on what is exactly required!
Start Time - 8:59
*Only have a short amount of time until Cath's Dad comes over. So just a bit of sorting first!
OK it doesn't just work to create a new Swift file to put values into. Nope that will not work!
*Just going to check how this worked with Angela's Quizzler app as mine doesn't have all of the info.
*Right various delays. The reason it does not work is because you need a class/struct to have the data model.
YES!!! IT worked!!
var seconds = 60
var timer = Timer()
var timeIsRunning = false
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
seconds -= 1
timerDisplay.text = String(seconds)
}
*More pauses - but a breakthrough! I've managed to get the time to reset after one game!
Now I need to get the timer starting again with a new game...
Update - I'd estimate that I've spent around an hour or so on this, with the various delays and Cath and her Dad being here.
Basically, I've got to the point where the time DOES stop at 0 at the end of the game. However, I cannot get it to start again! If I add in a method to get the timer starting again, it will just get to 0.
So that's all I can do! Really frustrating as the Medium tutorial did seem to genuinely work and I had some good breakthroughs.
Let's just have one more look...
YES! I got something - I've used the timeIsRunning variable to reset the timer. However, it will just keep going forever. What I need is some kind of 'start' button. That could do it!
I DID IT!!! IT's not the most elegant but it works! It seriously works! Next thing to do is to update all constraints, get timer to 60 then try it on my phone!!
import UIKit
import Foundation
class ViewController: UIViewController, UITextFieldDelegate {
//Global variables
var total = 1
var score = 0
var instructionInfo = "Enter The Number Of Words In The Box Above!"
//Timer
var seconds = 60
var timer = Timer()
var timeIsRunning = false
//Wordbank
let words = ["beagle", "unusual", "loins", "birthday", "category", "Catherine", "Josh", "Clint", "January", "degradation", "happening", "unfair", "whirlwind", "smashing", "turnover", "wooden", "systematic", "fairweather", "panglossian", "pilots", "factory", "radio", "multitude", "plethora", "inebriated", "certainly", "charity", "unfussed", "confidence", "shambles", "oblong", "indecisiveness", "unfamilar", "herald", "furniture", "randomisation", "alliteration", "carpenter", "surgeon", "worldly", "ineptidude", "longitude", "verisimilitude", "fragrant", "evuncular", "backdoor", "banana", "haemoglobin", "unfussy", "necktie", "bowtie", "disregard", "fatigued", "nondescript", "annhilation", "devastation", "happiness", "wonderful", "fabulous", "cucumber"]
//Outlets
@IBOutlet weak var timerDisplay: UILabel!
@IBOutlet weak var textFieldDisplay: UITextField!
@IBOutlet weak var wordDisplay: UILabel!
@IBOutlet weak var scoreLabel: UILabel!
@IBOutlet weak var questionLabel: UILabel!
@IBOutlet weak var instructionLabel: UILabel!
//Functions - buttons!
@IBAction func submitAnswerButton(_ sender: Any) {
hideKeyboard()
isAnswerCorrect()
}
@IBAction func newGameButton(_ sender: Any) {
newGame()
resetTimer()
updateScores()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
textFieldDisplay.delegate = self
newWord()
runTimer()
}
//Functions and Methods - keyboards etc.
func hideKeyboard() {
textFieldDisplay.resignFirstResponder()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textFieldDisplay.resignFirstResponder()
return true
}
//All other functions and methods
func runTimer() {
timeIsRunning = true
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
seconds -= 1
timerDisplay.text = String(seconds)
if seconds == 0 {
pauseTimer()
let alert = UIAlertController(title: "Game over!", message: "Your score was \(score) out of \(total)!", preferredStyle: .alert)
let action = UIAlertAction(title: "Click here to dismiss. Then select 'NEW GAME'!", style: .default, handler: {
action in self.submitAnswerButton(action)
})
alert.addAction(action)
present(alert, animated: true, completion: nil)
freezeScores()
}
}
func pauseTimer() {
timer.invalidate()
timeIsRunning = false
}
func resetTimer() {
if timeIsRunning == false {
runTimer()
seconds = 60
timerDisplay.text = String(seconds)
}
}
func newWord() {
let wordcount = words.count
let randomNumber = Int(arc4random_uniform(UInt32(wordcount)))
wordDisplay.text = words[randomNumber]
}
func updateScores() {
total += 1
questionLabel.text = "Question: \(total)"
}
func newGame() {
total = 0
score = 0
instructionLabel.text = instructionInfo
scoreLabel.text = "Score: 0"
}
func freezeScores() {
total = 0
score = 0
}
func isAnswerCorrect() {
if timeIsRunning == true {
let wordDisplayCount = wordDisplay.text?.count
let answer = textFieldDisplay.text
if Int(answer!) == wordDisplayCount {
instructionLabel.text = "Well done! You were right! You score one point!"
score += 1
scoreLabel.text = "Score: \(score)"
} else {
instructionLabel.text = "Unlucky! Try another word!"
}
updateScores()
newWord()
if total == 1 {
instructionLabel.text = instructionInfo
}
}
}
}
It's a complete success!! I am so proud. It works on my phone! Next thing is to try it on Cath's phone...Before that I need to have a 'reset' button. Or edit the New Game bit. Right forget that. Let's just get it working on Cath's phone!!
She's on the phone so just about to get it off so I can try it with her. If not, then she'll have to do it on mine!!
Well it worked! It worked really, really well! I feel so proud! There are things I can do to tweak and refine but that can be looked at tomorrow. Excellent stuff!
Total Time - two hours approx!
Comments
Post a Comment