How to make a Countdown Timer in iOS using Swift

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

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

class ViewController: UIViewController { @IBOutlet var timerLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ... } @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)! // ... } }
Code language: Swift (swift)

We set the event time we want:

class ViewController: UIViewController { @IBOutlet var timerLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ... } @objc func UpdateTime() { // ... // Set Event Date var eventDateComponents = DateComponents() eventDateComponents.year = 2021 eventDateComponents.month = 01 eventDateComponents.day = 01 eventDateComponents.hour = 00 eventDateComponents.minute = 00 eventDateComponents.second = 00 eventDateComponents.timeZone = TimeZone(abbreviation: "GMT") } }
Code language: Swift (swift)

If an event is happening at a particular time (e.g. a tv show starts at 8:00PM GMT) we can add the time zone alongside the date of this event.

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

class ViewController: UIViewController { @IBOutlet var timerLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ... } @objc func UpdateTime() { let userCalendar = Calendar.current // ... // Convert eventDateComponents to the user's calendar let eventDate = userCalendar.date(from: eventDateComponents)! } }
Code language: Swift (swift)

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

class ViewController: UIViewController { @IBOutlet var timerLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ... } @objc func UpdateTime() { let userCalendar = Calendar.current // ... // Change the seconds to days, hours, minutes and seconds let timeLeft = userCalendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: eventDate) } }
Code language: Swift (swift)

…and we display the results into our label:

class ViewController: UIViewController { @IBOutlet var timerLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ... } @objc func UpdateTime() { // ... // Display Countdown timerLabel.text = "\(timeLeft.day!)d \(timeLeft.hour!)h \(timeLeft.minute!)m \(timeLeft.second!)s" } }
Code language: Swift (swift)

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

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() { // ... } }
Code language: Swift (swift)

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.

class ViewController: UIViewController { @IBOutlet var timerLabel: UILabel! var timer: Timer! override func viewDidLoad() { super.viewDidLoad() // ... } @objc func UpdateTime() { // ... // 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() } } }
Code language: Swift (swift)

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() } } }
Code language: Swift (swift)
You can find the final project here

If you have any questionsplease feel free to leave a comment below

Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Bradley Manley

How do you code for a repeating 30 day countdown where it restarts every 30 days?