Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

How can I make a countdown with NSTimer?

Writer Olivia Zamora

How can I make a countdown with an NSTimer using Swift?

17 Answers

Question 1:

@IBOutlet var countDownLabel: UILabel!
var count = 10
override func viewDidLoad() { super.viewDidLoad() var timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true)
}
func update() { if(count > 0) { countDownLabel.text = String(count--) }
}

Question 2:

You can do both. SpriteKit is the SDK you use for scene, motion, etc. Simple View Application is the project template. They should not conflict

1

In Swift 5.1 this will work:

var counter = 30
override func viewDidLoad() { super.viewDidLoad() Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
}
@objc func updateCounter() { //example functionality if counter > 0 { print("\(counter) seconds to the end of the world") counter -= 1 }
}
2

Swift 5 with Closure:

class ViewController: UIViewController {
var secondsRemaining = 30
@IBAction func startTimer(_ sender: UIButton) { Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (Timer) in if self.secondsRemaining > 0 { print ("\(self.secondsRemaining) seconds") self.secondsRemaining -= 1 } else { Timer.invalidate() } }
}
3

Swift 4.1 and Swift 5. The updatetime method will called after every second and seconds will display on UIlabel.

 var timer: Timer? var totalTime = 60 private func startOtpTimer() { self.totalTime = 60 self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTimer), userInfo: nil, repeats: true) } @objc func updateTimer() { print(self.totalTime) self.lblTimer.text = self.timeFormatted(self.totalTime) // will show timer if totalTime != 0 { totalTime -= 1 // decrease counter timer } else { if let timer = self.timer { timer.invalidate() self.timer = nil } } } func timeFormatted(_ totalSeconds: Int) -> String { let seconds: Int = totalSeconds % 60 let minutes: Int = (totalSeconds / 60) % 60 return String(format: "%02d:%02d", minutes, seconds) }
1

Variable for your timer

var timer = 60

NSTimer with 1.0 as interval

var clock = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "countdown", userInfo: nil, repeats: true)

Here you can decrease the timer

func countdown() { timer--
}
2

Swift 3

private let NUMBER_COUNT_DOWN = 3
var countDownLabel = UILabel()
var countDown = NUMBER_COUNT_DOWN
var timer:Timer?
private func countDown(time: Double)
{ countDownLabel.frame = CGRect(x: 0, y: 0, width: 300, height: 300) countDownLabel.font = UIFont.systemFont(ofSize: 300) countDownLabel.textColor = .black countDownLabel.center = CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height / 2) countDownLabel.textAlignment = .center self.view.addSubview(countDownLabel) view.bringSubview(toFront: countDownLabel) timer = Timer.scheduledTimer(timeInterval: time, target: self, selector: #selector(updateCountDown), userInfo: nil, repeats: true)
}
func updateCountDown() { if(countDown > 0) { countDownLabel.text = String(countDown) countDown = countDown - 1 } else { removeCountDownLable() }
}
private func removeCountDownLable() { countDown = NUMBER_COUNT_DOWN countDownLabel.text = "" countDownLabel.removeFromSuperview() timer?.invalidate() timer = nil
}

XCode 10 with Swift 4.2

import UIKit
class ViewController: UIViewController { var timer = Timer() var totalSecond = 10 override func viewDidLoad() { super.viewDidLoad() startTimer() } func startTimer() { timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true) } @objc func updateTime() { print(timeFormatted(totalSecond)) if totalSecond != 0 { totalSecond -= 1 } else { endTimer() } } func endTimer() { timer.invalidate() } func timeFormatted(_ totalSeconds: Int) -> String { let seconds: Int = totalSeconds % 60 return String(format: "0:%02d", seconds) }
}

Swift 5 another way. Resistant to interaction with UI

I would like to show a solution that is resistant to user interaction with other UI elements during countdown. In the comments I explained what each line of code means.

 var timeToSet = 0 var timer: Timer? ... @IBAction func btnWasPressed(_ sender: UIButton) { //Setting the countdown time timeLeft = timeToSet //Disabling any previous timers. timer?.invalidate() //Initialization of the Timer with interval every 1 second with the function call. timer = Timer(timeInterval: 1.0, target: self, selector: #selector(countDown), userInfo: nil, repeats: true) //Adding Timer to the current loop RunLoop.current.add(timer!, forMode: .common) } ... @objc func countDown() { if timeLeft > 0 { print(timeLeft) timeLeft -= 1 } else { // Timer stopping timer?.invalidate() } }

For use in Playground for fellow newbies, in Swift 5, Xcode 11:

Import UIKit
var secondsRemaining = 10
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (Timer) in if secondsRemaining > 0 { print ("\(secondsRemaining) seconds") secondsRemaining -= 1 } else { Timer.invalidate() }
}
3

Swift 4

Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateTime), userInfo: nil, repeats: true)

Update function

@objc func updateTime(){ debugPrint("jalan")
}

Swift4

 @IBOutlet weak var actionButton: UIButton! @IBOutlet weak var timeLabel: UILabel! var timer:Timer? var timeLeft = 60
override func viewDidLoad() { super.viewDidLoad() setupTimer()
}
func setupTimer() { timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(onTimerFires), userInfo: nil, repeats: true)
}
@objc func onTimerFires() { timeLeft -= 1 timeLabel.text = "\(timeLeft) seconds left" if timeLeft <= 0 { actionButton.isEnabled = true actionButton.setTitle("enabled", for: .normal) timer?.invalidate() timer = nil }
}
@IBAction func btnClicked(_ sender: UIButton) { print("API Fired")
}

this for the now swift 5.0 and newst

var secondsRemaining = 60
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
}
@objc func updateCounter(){ if secondsRemaining > 0 { print("\(secondsRemaining) seconds.") secondsRemaining -= 1 } }

Make Countdown app Xcode 8.1, Swift 3

import UIKit
import Foundation
class ViewController: UIViewController, UITextFieldDelegate { var timerCount = 0 var timerRunning = false @IBOutlet weak var timerLabel: UILabel! //ADD Label @IBOutlet weak var textField: UITextField! //Add TextField /Enter any number to Countdown override func viewDidLoad() { super.viewDidLoad() //Reset timerLabel.text = "" if timerCount == 0 { timerRunning = false }
} //Figure out Count method func Counting() { if timerCount > 0 { timerLabel.text = "\(timerCount)" timerCount -= 1 } else { timerLabel.text = "GO!" } } //ADD Action Button @IBAction func startButton(sender: UIButton) { //Figure out timer if timerRunning == false { _ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.Counting), userInfo: nil, repeats: true) timerRunning = true } //unwrap textField and Display result if let countebleNumber = Int(textField.text!) { timerCount = countebleNumber textField.text = "" //Clean Up TextField } else { timerCount = 3 //Defoult Number to Countdown if TextField is nil textField.text = "" //Clean Up TextField } } //Dismiss keyboard func keyboardDismiss() { textField.resignFirstResponder() } //ADD Gesture Recignizer to Dismiss keyboard then view tapped @IBAction func viewTapped(_ sender: AnyObject) { keyboardDismiss() } //Dismiss keyboard using Return Key (Done) Button func textFieldShouldReturn(_ textField: UITextField) -> Bool { keyboardDismiss() return true }
}

Add this to the end of your code... and call startTimer function with a parameter of where you want to count down to... For example (2 hours to the future of the date right now) -> startTimer(for: Date().addingTimeInterval(60*60*2))

Click here to view a screenshot of iPhone Simulator of how it'll look

extension ViewController
{ func startTimer(for theDate: String) { let todaysDate = Date() let tripDate = Helper.getTripDate(forDate: theDate) let diffComponents = Calendar.current.dateComponents([.hour, .minute], from: Date(), to: tripDate) if let hours = diffComponents.hour { hoursLeft = hours } if let minutes = diffComponents.minute { minutesLeft = minutes } if tripDate > todaysDate { timer = Timer.scheduledTimer(timeInterval: 1.00, target: self, selector: #selector(onTimerFires), userInfo: nil, repeats: true) } else { timerLabel.text = "00:00:00" } } @objc func onTimerFires() { secondsLeft -= 1 //timerLabel.text = "\(hoursLeft):\(minutesLeft):\(secondsLeft)" timerLabel.text = String(format: "%02d:%02d:%02d", hoursLeft, minutesLeft, secondsLeft) if secondsLeft <= 0 { if minutesLeft != 0 { secondsLeft = 59 minutesLeft -= 1 } } if minutesLeft <= 0 { if hoursLeft != 0 { minutesLeft = 59 hoursLeft -= 1 } } if(hoursLeft == 0 && minutesLeft == 0 && secondsLeft == 0) { timer.invalidate() } }
}
import UIKit
class ViewController: UIViewController { let eggTimes = ["Soft": 300, "Medium": 420, "Hard": 720] var secondsRemaining = 60 @IBAction func hardnessSelected(_ sender: UIButton) { let hardness = sender.currentTitle! secondsRemaining = eggTimes[hardness]! Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true) } @objc func countDown() { if secondsRemaining > 0 { print("\(secondsRemaining) seconds.") secondsRemaining -= 1 } }
}
2

You really shouldn’t. Grand Central Dispatch is much more reliable.

this is an egg timer.

import UIKit
class ViewController: UIViewController { let eggTimes = ["Soft": 0.1, "Medium": 2, "Hard": 3] var eggTime = 0 var timer = Timer() @IBOutlet weak var label: UILabel! @IBAction func b(_ sender: UIButton) { timer.invalidate() let hardness = sender.currentTitle! eggTime = Int(eggTimes[hardness]! * 60) timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(update), userInfo: nil, repeats: true) } @objc func update() { if (eggTime > 0) { print("\(eggTime) seconds") eggTime -= 1 } if (eggTime == 0){ label.text = ("done") } }
}

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy