In this tutorial, we’ll be discussing and implementing the Timer class. We’ll be developing an iOS Application which runs a Countdown Timer.


A Timer class is that fires a method at certain intervals.

To create a Timer:

Timer.scheduledTimer(timeInterval: 1, target: self,   selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)

The above timer runs every second. The function passed in the selector gets triggered on every timeInterval.
Setting repeats to false would imply that the timer would be fired just once.
A nonrepeating timer fires once and then invalidates itself automatically.

Timer class has replaced the earlier NSTimer class in Swift.

UserInfo is where we can pass some extra data which can be retrieved from the Timer instance later on.

let context = ["user": "@anupam"]
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(myTimer), userInfo: context, repeats: true)

@objc func myTimer(timer: Timer) {
    guard let context = timer.userInfo as? [String: String] else { return }
    let user = context["user", default: "NA"]
    print("Timer fired by (user)!")

The data passed inside the UserInfo is a Dictionary.

To stop a Timer we can simply call:


invalidate() stops the Timer from firing again and removes the Timer from the running loop.

Instead of adding a selector function which gets triggered, we can use a closure to run the desired action whenever the Timer is fired.

 _ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
        label.isHidden = true

In the next section, we’ll be creating a Countdown Timer iOS Application with play/pause/reset buttons.
Also, we’ll format the time to show the hours, minutes, seconds properly in the Label.

Project Storyboard


Connect the IBOutlet for the Buttons and Label and the IBAction for the Buttons to the ViewController using Control and Drag.


The code for the ViewController.swift is given below:

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var myLabel: UILabel!
    @IBOutlet weak var playButton: UIButton!
    @IBOutlet weak var pauseButton: UIButton!
    var seconds = 60
    var timer = Timer()
    var hasTimerStarted = false
    var isResumed = false
    override func viewDidLoad() {
        self.pauseButton.isEnabled = false
    func runTimer() {
        timer = Timer.scheduledTimer(timeInterval: 1, target: self,   selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
        self.pauseButton.isEnabled = true
    @objc func updateTimer() {
        if seconds  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)
    @IBAction func playClicked(_ sender: Any) {
        if hasTimerStarted == false {
            self.playButton.isEnabled = false
    @IBAction func pauseClicked(_ sender: Any) {
        if self.isResumed == false {
            hasTimerStarted = false
            self.isResumed = true
            self.pauseButton.setTitle("Resume",for: .normal)
        } else {
            self.isResumed = false
            hasTimerStarted = true
            self.pauseButton.setTitle("Pause",for: .normal)
    @IBAction func resetClicked(_ sender: Any) {
        seconds = 360
        myLabel.text = formattedTime(time: TimeInterval(seconds))
        hasTimerStarted = false
        isResumed = false
        self.pauseButton.setTitle("Pause",for: .normal)
        pauseButton.isEnabled = false
        self.playButton.isEnabled = true

The formattedTime function is where we format the time to be displayed on the label.
We need to carefully toggle the Pause button text and keep a flag on it to check its current state.
When the Reset Button is clicked, everything is stopped and reset with a new countdown of 6 minutes.

The output of the application in action is given below:

ios timer output

This brings an end to this tutorial. You can download the project from the link below:

By admin

Leave a Reply

%d bloggers like this: