Swift 3: Programming a simple stopwatch

Swift 3: Programming a simple stopwatch

Published March 3, 2017 by 3 Comments

For the last while, I have been extending my programming skill set by learning Swift. Swift is a programming language for MacOS, iOS, watchOS and tvOS applications. As both a resource for myself and hopefully a resource for fellow programmers, I thought I might start publishing some of my early scratchings. I emphasise early! Don’t expect the entire source code to an Uber app… yet.

The following code creates a simple stopwatch/timer. It could be easily extended to include advanced functionality like reverse timers, alarms, notifications, etc. I learnt a lot from this so I hope it may be useful to your Swift journey. I would love any feedback so feel free to comment.

Swift 4 Programming Cookbook: 50 task-oriented recipes to make you productive with Swift 4

The book begins with an introduction to the basic building blocks of Swift 4, its syntax and the functionalities of Swift constructs. Then, introduces you to Apple’s Xcode 9 IDE and Swift Playgrounds, which provide an ideal platform to write, execute, and debug the codes thus initiating your development process. Next, you’ll learn to bundle variables into tuples, set order to your data with an array, store key-value pairs with dictionaries and you’ll learn how to use the property observers. Later, explore the decision-making and control structures in Swift and learn how to handle errors in Swift 4.

I used the following very helpful sources when researching how I should approach this Swift snippet:

I separated the three time blocks (min/sec/ms) into separate labels as I found that putting them all into one label made for a shaky viewing experience. I suspect by having them separate will allow for easy design enhancements.

//  ViewController.swift
//  Simple Stopwatch
//  Created by Mike Little on 2/03/17.
//  Copyright © 2017 Creative Digital. All rights reserved.

import UIKit

class ViewController: UIViewController {

    weak var timer: Timer?
    var startTime: Double = 0
    var time: Double = 0
    var elapsed: Double = 0
    var status: Bool = false
    @IBOutlet weak var labelMinute: UILabel!
    @IBOutlet weak var labelSecond: UILabel!
    @IBOutlet weak var labelMillisecond: UILabel!
    @IBOutlet weak var resetBtn: UIButton!
    override func viewDidLoad() {
        // Do any additional setup after loading the view, typically from a nib.
        // No point enabling reset until stopwatch actually started
        resetBtn.isEnabled = false

    override func didReceiveMemoryWarning() {
        // Dispose of any resources that can be recreated.

    @IBAction func toggleStartStop(_ sender: UIButton!) {
        // If button status is true use stop function, relabel button and enable reset button
        if (status) {
            sender.setTitle("START", for: .normal)
            resetBtn.isEnabled = true
        // If button status is false use start function, relabel button and disable reset button
        } else {
            sender.setTitle("STOP", for: .normal)
            resetBtn.isEnabled = false
    @IBAction func resetBtn(_ sender: Any) {
        // Invalidate timer
        // Reset timer variables
        startTime = 0
        time = 0
        elapsed = 0
        status = false
        // Reset all three labels to 00
        let strReset = String("00")
        labelMinute.text = strReset
        labelSecond.text = strReset
        labelMillisecond.text = strReset
    func start() {
        startTime = Date().timeIntervalSinceReferenceDate - elapsed
        timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
        // Set Start/Stop button to true
        status = true

    func stop() {
        elapsed = Date().timeIntervalSinceReferenceDate - startTime
        // Set Start/Stop button to false
        status = false
    func updateCounter() {
        // Calculate total time since timer started in seconds
        time = Date().timeIntervalSinceReferenceDate - startTime
        // Calculate minutes
        let minutes = UInt8(time / 60.0)
        time -= (TimeInterval(minutes) * 60)
        // Calculate seconds
        let seconds = UInt8(time)
        time -= TimeInterval(seconds)
        // Calculate milliseconds
        let milliseconds = UInt8(time * 100)
        // Format time vars with leading zero
        let strMinutes = String(format: "%02d", minutes)
        let strSeconds = String(format: "%02d", seconds)
        let strMilliseconds = String(format: "%02d", milliseconds)
        // Add time vars to relevant labels
        labelMinute.text = strMinutes
        labelSecond.text = strSeconds
        labelMillisecond.text = strMilliseconds


Mastering Swift 3

Dive into the latest release of the Swift programming language with this advanced Apple development book.

  • Discover the new features and improvements to Swift 3
  • Get to grips with advanced design patterns and techniques to write smarter, cleaner Swift code
  • Become a more fluent Swift developer and build powerful, impressive iOS and OS X applications.

This book is for developers who want to dive into the newest version of Swift. If you are a developer that learns best by looking at, and working with code, then this book is for you. A basic understanding of Apple’s tools is beneficial but not mandatory.

Buy on Amazon: http://amzn.to/2mnuY8w

Tags: , , ,


  • John kirk says:

    if I setup the timer for 10 seconds, then I need to start another timer for 5 seconds after the first timer stopped before the first timer running back?
    I stopped the first one after 10 seconds, but the second timer started but stop counting!

    appreciated your help,

  • Max Schellenberg says:

    Hey there, thanks this helped. How would I count down from 30 seconds?

Leave a Reply

Your email address will not be published. Required fields are marked *