Building a small timer app, why won't app timer stop both labels? - swift

I'm in the process of building a timer app
I have a button that starts the timer and changes both labels
I have another button that stops the timer with .invalidete.
the problem is when the timer starts both labels change at the set rate they are suppose to
But when I hit the stop button only the 2nd timer label stops changing, the 1st label seems to keep going I don't know why
import UIKit
class ViewController: UIViewController {
var timer = NSTimer()
var counter = 0
var counter2 = 0
#IBOutlet weak var label: UILabel!
#IBOutlet weak var label2: UILabel!
#IBAction func start(sender: AnyObject){
counter = 0
label.text = String(counter)
timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "updateCounter", userInfo: nil, repeats: true)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateCounter2", userInfo: nil, repeats: true)
}
func updateCounter2(){
counter2 += 1
label2.text = String(counter2)
}
func updateCounter(){
counter += 1
label.text = String(counter)
}
#IBAction func stop(sender: AnyObject) {
timer.invalidate()
timer.invalidate()
}
}

What you wan't to do is something like this:
var timer:NSTimer!
var timer2:NSTimer!
var counter = 0
var counter2 = 0
#IBOutlet weak var label: UILabel!
#IBOutlet weak var label2: UILabel!
#IBAction func start(sender: AnyObject){
counter = 0
label.text = String(counter)
timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "updateCounter", userInfo: nil, repeats: true)
timer2 = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateCounter2", userInfo: nil, repeats: true)
}
func updateCounter2(){
counter2 += 1
label2.text = String(counter2)
}
func updateCounter(){
counter += 1
label.text = String(counter)
}
#IBAction func stop(sender: AnyObject) {
timer.invalidate()
timer2.invalidate()
}
Watch this talk in value types from WWDC 2015, it explains a couple of things about OOP that you might find useful.

Related

xcode 10.1: Timer stops at 1 not 0

Yep, I have seen a few questions similar to mine but for some reason, I couldn't duplicate it! If I use == or <= with If both are giving me stop at 1. The only < gave me the 0 stops which are good, but very rare I got -1. Any help, please?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var startButton: UIButton!
var timer = Timer()
var timeLeft = 10
override func viewDidLoad() {
timeLabel.text = String(10)
super.viewDidLoad()
}
#IBAction func pressTimer(_ sender: Any) {
startButton.isEnabled = false
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(startTime), userInfo: nil, repeats: true)
}
#objc func startTime() {
timeLeft -= 1
timeLabel.text = "\(timeLeft)"
if timeLeft < 0 {
startButton.isEnabled = false
self.timer.invalidate()
}
}
}
My suggestion is to declare the timer as optional and check for zero before decrementing the counter.
And set the counter to 10 in the pressTimer method
class ViewController: UIViewController {
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var startButton: UIButton!
var timer : Timer?
var timeLeft = 0
#IBAction func pressTimer(_ sender: Any) {
startButton.isEnabled = false
timeLeft = 10
timeLabel.text = String(timeLeft)
if timer == nil {
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(startTime), userInfo: nil, repeats: true)
}
}
#objc func startTime()
{
if timeLeft == 0 {
startButton.isEnabled = false // shouldn't it be true??
timer?.invalidate()
timer = nil
} else {
timeLeft -= 1
timeLabel.text = String(timeLeft)
}
}
}

Run Counter while button press

I am very new to swift and I want to make a button work like this:
Press the Button and hold. While the Button is pressed the label value goes up like every second +1 until the button is released.
This is what I get so far:
class ViewController: UIViewController {
var counter = 0;
override func viewDidLoad() {
super.viewDidLoad();
}
#IBOutlet weak var label: UILabel!
#IBAction func btn(_ sender: Any) {
if (sender as AnyObject).state != .ended{
counter+=1;
// wait 100ms
self.label.text = String (counter);
}
}
}
This is how I linked it:
You can achieve this using the UIButton actions Touch Down and Touch Up Inside
class ViewController: UIViewController {
var timer : Timer?
var startTime = 0
var timerReset = true // I don't know what logic you want. This basically has been added so the number is not set to 0 immediately when you release the button. You can also add another button to reset startTime variable and the label
#IBOutlet weak var numberLabel: UILabel!
#IBOutlet weak var numberButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
numberLabel.text = String(startTime) //initial value
// Do any additional setup after loading the view.
}
#IBAction func holdingTheButton(_ sender: Any) {
print("I am holding")
timerReset = false // reset to false since you are holding the button
guard timer == nil else { return }
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}
#IBAction func buttonReleased(_ sender: Any) {
print("button released")
startTime = 0
timer?.invalidate()
timer = nil
timerReset = true // reset to true since you released.
}
#objc func updateTime(){
//update label every second
print("updating label ")
if timerReset {
startTime = 0
}
startTime += 1
numberLabel.text = String(startTime)
}
}
IMPORTANT: Make sure you are connecting in the right way. Touch Down has to be used if you want to call the function while you hold the button:
In your console, you should see this happening if you release the button after 10 SECONDS:
If you want to have a button to reset, you can just add the it and then connect it to the following function (but also make sure you remove the bool timeReset and the if statement inside updateTime:
#IBAction func resetTimer(_ sender: Any) {
startTime = 0
numberLabel.text = String(startTime)
}
You can achieve it using two sent event touch of UIButton and a Timer.
var counter = 0
var timer: Timer?
#IBAction func buttonTouchUpInside(_ sender: Any) {
timer?.invalidate()
print(counter)
}
#IBAction func buttonTouchDown(_ sender: Any) {
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(increaseCount), userInfo: nil, repeats: true)
}
#objc func increaseCount() {
counter += 1
print(counter)
}

Timer class, not increasing count

I'm not sure where I did wrong. I don't see any error, but the count isn't increasing.
#IBOutlet weak var myTimerLabel: UILabel!
let myTimer = Timer()
#objc func myTestFunc() {
var count = 0
count+=1
myTimerLabel.text = String(count)
}
override func viewDidLoad() {
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector
(myTestFunc), userInfo: nil, repeats: true)
}
Its not increasing because each time myTestFunc() called, it reinitialize the count variable with zero. So, declare count variable outside myTestFunc().
You have to make structure in right way
check this:
#IBOutlet weak var myTimerLabel: UILabel!
let myTimer = Timer()
var count = 0
//MARK: - view did load
override func viewDidLoad() {
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector (myTestFunc), userInfo: nil, repeats: true)
}
//TODO:- here implement your funtion
#objc func myTestFunc() {
count+=1
myTimerLabel.text = String(count)
// if you want to stop your timer
myTimer.invalidate()
}
Good luck

How do I set a label to a value from a separate table view controller?

So I'm setting up a timer in swift that takes text entered from another view controller. I'm not sure how to set the timer label as the value "timerTime" which has a member called "time" from another controller.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var pauseButton: UIButton!
#IBOutlet weak var startButton: UIButton!
#IBOutlet weak var timerTaskName: UILabel!
#IBOutlet weak var timerTimeSetting: UILabel!
var timerTask: TaskData?
var timerTime: TaskData?
var seconds = 100
var timer = Timer()
var isTimerRunning = false
var resumeTapped = false
#IBAction func cancel(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func startButtonTapped(_ sender: Any) {
if isTimerRunning == false {
runTimer()
self.startButton.isEnabled = false
}
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
isTimerRunning = true
pauseButton.isEnabled = true
}
#IBAction func pauseButtonTapped(_ sender: UIButton) {
if self.resumeTapped == false {
timer.invalidate()
self.resumeTapped = true
self.pauseButton.setTitle("Resume",for: .normal)
} else {
runTimer()
self.resumeTapped = false
self.pauseButton.setTitle("Pause",for: .normal)
}
}
#IBAction func resetButtonTapped(_ sender: Any) {
timer.invalidate()
seconds = 60
self.timerLabel.text = timeString(time: TimeInterval(seconds))
if self.resumeTapped == true {
self.resumeTapped = false
self.pauseButton.setTitle("Pause",for: .normal)
}
isTimerRunning = false
pauseButton.isEnabled = false
startButton.isEnabled = true
}
func updateTimer() {
if seconds < 1 {
timer.invalidate()
//Send alert to indicate "time's up!"
} else {
seconds -= 1
timerLabel.text = timeString(time: TimeInterval(seconds))
}
}
func timeString(time:TimeInterval) -> String {
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i:%02i", hours, minutes, seconds)
}
override func viewDidLoad() {
super.viewDidLoad()
pauseButton.isEnabled = false
if let task = timerTask {
timerTaskName.text = task.task
}
if let timerTimeLeft = timerTime {
timerTimeSetting.text = timerTimeLeft.time
}
self.timerLabel.text = timeString(time: TimeInterval(seconds))
}
}
Essentially I'm trying to get timerTimeLeft.time into my seconds variable. I've tried many different things but at I'm just stuck.
You need to add the timer to the runloop. This:
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
isTimerRunning = true
pauseButton.isEnabled = true
}
Should be
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: .defaultRunLoopMode) // <-- Notice this
isTimerRunning = true
pauseButton.isEnabled = true
}

Stopwatch code Issue

I am trying to create a stopwatch app, for some reason when I press the start button in the app, instead of it going, 1,2,3,4,5 etc. It shows this '<'. I have gone over the code but I can find nothing.
class ViewController: UIViewController {
var timer = NSTimer()
var time = 0
func result() {
time + 1
timeLabel.text = "\(timer)"
}
#IBOutlet var timeLabel: UILabel!
#IBAction func stop(sender: AnyObject) {
timer.invalidate()
time = 0
timeLabel.text = "0"
}
#IBAction func timeButton(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("result"), userInfo: nil, repeats: true)
}
}
You have a typo: timeLabel.text = "\(timer)" should be timeLabel.text = "\(time)".
Also, time + 1 should be time += 1. With those changes, the following code works:
class ViewController: UIViewController {
var timer = NSTimer()
var time = 0
func result() {
time += 1
timeLabel.text = "\(time)"
}
#IBOutlet var timeLabel: UILabel!
#IBAction func stop(sender: AnyObject) {
timer.invalidate()
time = 0
timeLabel.text = "0"
}
#IBAction func timeButton(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(result), userInfo: nil, repeats: true)
}
}