How can I make a countdown with an NSTimer
using Swift?
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
}
}
https://github.com/nikae/CountDown-
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()
}
}
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()
}
}
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()
}
}
}
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 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()
}
}
}