How to make a Countdown Timer in iOS using Swift

How to make a Countdown Timer in iOS using Swift

Today, I will show how to build a timer that count down until an event (e.g. new year’s day or release date of a video game) using the scheduledTimer of the Timer class to refresh it every second.

First, we set the current date using the calendar user use on their device.

let userCalendar = Calendar.current
// Set Current Date
let date = Date()
let components = userCalendar.dateComponents([.hour, .minute, .month, .year, .day, .second], from: date)
let currentDate = userCalendar.date(from: components)!

We set the event time we want:

// Set Event Date
var eventDateComponents = DateComponents()
eventDateComponents.year = 2020
eventDateComponents.month = 01
eventDateComponents.day = 01
eventDateComponents.hour = 00
eventDateComponents.minute = 00
eventDateComponents.second = 00
eventDateComponents.timeZone = TimeZone(abbreviation: "GMT")

If an event is happening at a particular time (e.g. Worldwide premiere of a video game release starts at 8:00PM GMT) we can add the time zone alongside with the date of this event.

We convert the event date to the user’s calendar:

// Convert eventDateComponents to the user's calendar
let eventDate = userCalendar.date(from: eventDateComponents)!

We change the seconds to days, hours, minutes and seconds:

// Change the seconds to days, hours, minutes and seconds
let timeLeft = userCalendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: eventDate)

…and we display the results into our label:

// Display Countdown
timerLabel.text = "\(timeLeft.day!)d \(timeLeft.hour!)h \(timeLeft.minute!)m \(timeLeft.second!)s"

Last, we add the Timer in our viewDidLoad(), and set it to repeat the function every second:

var timer: Timer!
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(UpdateTime), userInfo: nil, repeats: true) // Repeat "func Update() " every second and update the label
}

If you want to change the label after the event has passed, you can do this by checking if the current date is after the event. If yes, then will stop the timer and show the text.

func endEvent(currentdate: Date, eventdate: Date) {
if currentdate >= eventdate {
timerLabel.text = "Happy New Year!"
// Stop Timer
timer.invalidate()
}
}

So at the end, our ViewController looks like this:

class ViewController: UIViewController {
@IBOutlet var timerLabel: UILabel!
var timer: Timer!
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(UpdateTime), userInfo: nil, repeats: true) // Repeat "func Update() " every second and update the label
}
@objc func UpdateTime() {
let userCalendar = Calendar.current
// Set Current Date
let date = Date()
let components = userCalendar.dateComponents([.hour, .minute, .month, .year, .day, .second], from: date)
let currentDate = userCalendar.date(from: components)!
// Set Event Date
var eventDateComponents = DateComponents()
eventDateComponents.year = 2020
eventDateComponents.month = 01
eventDateComponents.day = 01
eventDateComponents.hour = 00
eventDateComponents.minute = 00
eventDateComponents.second = 00
eventDateComponents.timeZone = TimeZone(abbreviation: "GMT")
// Convert eventDateComponents to the user's calendar
let eventDate = userCalendar.date(from: eventDateComponents)!
// Change the seconds to days, hours, minutes and seconds
let timeLeft = userCalendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: eventDate)
// Display Countdown
timerLabel.text = "\(timeLeft.day!)d \(timeLeft.hour!)h \(timeLeft.minute!)m \(timeLeft.second!)s"
// Show diffrent text when the event has passed
endEvent(currentdate: currentDate, eventdate: eventDate)
}
func endEvent(currentdate: Date, eventdate: Date) {
if currentdate >= eventdate {
timerLabel.text = "Happy New Year!"
// Stop Timer
timer.invalidate()
}
}
}
You can find the final project here

If you have any questions feel free to DM me on Twitter @johncodeos or leave a comment below!

Leave a Reply

avatar
  Subscribe  
Notify of

Stay Connected

Newsletter

Subcribe for weekly emails! Get my posts of the week right in your inbox!