Swift 3: Programming a simple stopwatch

Swift 3: Programming a simple stopwatch

Published March 3, 2017 by 1 Comment

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 Data Structure and Algorithms

Master the most common algorithms and data structures, and learn how to implement them efficiently using the most up-to-date features of Swift 3.

About This Book
Develop a deep understanding of the collections in the Swift Standard Library with this step-by-step guide. Develop native Swift data structures and algorithms for use in mobile, desktop, and server-based applications. Learn about performance efficiency between different data structures and algorithms.

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,

Leave a Reply

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