Full Disclosure: I am extremely new to everything swift/UIKit-related so I hope you can excuse my assured ignorance.
So the basic action I am trying to preform is having a Timer immediately begin a countdown the moment any character is entered into a UITextField (NOT triggered just by being focused).
Everything looks and functions 90% as I am intending except for an interaction where every time a character is entered into text field, the timer recursively initiates it's timeInterval.
After 7+ characters are typed, my 60-Second timer is far past 0 in less than a few seconds.
Using editingDidBegin "fixes" the issue but, in this parameter, the timer starts when the text field is tapped and focused and that isn't ideal for what I am trying to do.
My ViewController Code:
import UIKit
class SecondViewController: UIViewController, UITextFieldDelegate {
var textField: UITextField?
@IBOutlet weak var countDownLabel: UILabel!
var seconds = 60
var timer = Timer()
@IBAction func inputTextBar(_ sender: Any) {
func inputTextBar() {
self.becomeFirstResponder()
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(SecondViewController.counterb), userInfo: nil, repeats: true)
}
@objc func counterb() {
seconds -= 1
countDownLabel.text = String(seconds)
if seconds == 0 {
timer.invalidate()
countDownLabel.text = "Time's Up!"
}
}
var count = 10
override func viewDidLoad() {
super.viewDidLoad()
textField?.delegate = self
textField?.becomeFirstResponder()
}
}
Other Noted Confusion: If only one character is typed, the timer proceeds as normal and prints "Times Up!" at 0sec. and stops.
But if it's on the speed-pileup I mentioned, after a few characters are typed, the timer flies past 0 and never invalidates.
I assume that's a refresh issue.
Edit:
Okay, I figured out that making the timer variable weak I was able to get the timer to not keep stacking on itself. But, with the weak variable, the timer doesn't run at all while the UITextField is being typed in!
Semi-Fixed Code:
weak var timer: Timer?
@IBAction func inputTextBar(_ sender: AnyObject) {
timer?.invalidate()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(SecondViewController.loop), userInfo: nil, repeats: true)
}
@objc func loop() {
seconds -= 1
countDownLabel.text = String(seconds)
if self.seconds == 0 {
timer?.invalidate()
countDownLabel.text = "Time's Up!"
}
}