Make a Count Up Timer using Swift and SwiftUI
Tags: swiftui, swift
Published: 2020-05-12 04:03:57

---
title: Make a Count Up Timer using Swift and SwiftUI
description: In this post, we are going to make a count up timer using Swift and SwiftUI
tags: [SwiftUI, Swift]
published: true
canonical_url: https://medium.com/better-programming/how-to-build-a-timer-using-swift-and-swiftui-e72cd8eb3d3a
---

In this post, we are going to make a count up timer using Swift and SwiftUI. This will walk you through step by step from making a new app to running the finished timer.

The finished project can be cloned from [GitLab](https://gitlab.com/appsbymw/count-up-timer) here.

# Step 1: Launch a new project

Launch a new project in Xcode. The template needs to be a Single View App. The language needs to be set to Swift and the User Interface needs to be set to SwiftUI. You can set the `Product Name` to be whatever you'd like. I'm calling mine **Count Up Timer**.

![Image of new project](https://appsbymw.com/assets/images/2020-05-01/001_new_project.png)

# Step 2: Add variables

Let's add variables to hold the hours, minutes, and seconds that are needed to be displayed on the screen.

In `ContentView.swift`, add lines 6 through 8 in the gist below.

{% gist https://gist.github.com/appsbymw/a61b3d1fe09d5cd5e8f0e3c2d08db4f3 %}

These three variables, `hours`, `minutes`, and `seconds` are declared with the `@State` property wrapper so that the text updates when the value updates. You can read more about the `@State` property wrapper here on [Apple's website](https://developer.apple.com/documentation/swiftui/state).

# Step 3: "Design" the UI

Now, let's actually design the UI. It's going to have the timer in the middle, then buttons to start/pause the timer and to reset the timer back to 0.

The first thing we need to do is add a VStack in the `body`. To do this, you can right click on the `Text("Hello, World!")` and choose **Embed in VStack**. Your code should now look like the gist below.

{% gist https://gist.github.com/appsbymw/201970fa0b46557c56317965ea940cf0 %}

## Show the timer values

Then, we need to put the variabled in. We are going to change the `Hello, World!` to `\(hours):\(minutes):\(seconds)`. If you open the Canvas and resume it, then you should see 0:0:0 in the device.

You might be asking why use `\()` around the variable name. The slash and parenthesis are needed to tell the compiler that there is code inside the parenthesis. Therefore, the program will display the contents of the variable and not the variables name.

## Add Buttons

Now, let's add the buttons and make them do something!

First, we are going to add a new state variable that signifies if the timer has started or been paused. Right after the declaration of `seconds`, add `@State var timerIsPaused: Bool = true`.

Then, after `Text()` we need to add an if statement that is going to show a view when the timer is paused and when it's going. The gist below shows what the view should look like with that if statement. 

{% gist https://gist.github.com/appsbymw/6ebe2cb6007618ed4e7ca7fe79704d1c %}

Now, we are going to change Text to Buttons and use SF Symbol for Start, Pause, and Reset.

If `timerIsPaused` is true, then we want to show a play icon for start and a backward icon for reset. To do this, we need to use the `Image(systemName: String)` as the Button labels. These two buttons also need to be in a HStack to be next to each other. Now, if `timerIsPaused` is false, we need to show a pause icon to stop the timer. The gist below shows the buttons in the if statement.

{% gist https://gist.github.com/appsbymw/0e57fd27d629638c547ae811095a1a15 %}

That's what it took to "design" this app in SwiftUI. Next, we are going to make the parts functional.

# Step 4: Start the timer

It's time to actually get the timer going. We are going to use the [`Timer`](https://developer.apple.com/documentation/foundation/timer) that's buit into Swift. We will need to make a repeating timer that adds one second every second. 

Let's add a variable for the state first, so after `timerIsPaused`, add `@State var timer: Timer? = nil`. This declares a variable to store the timer in, but doesn't actually store a Timer to the variable, yet, since we will call a new Timer when the timer starts.

Next we need to write a function that starts the timer and changed `timerIsPaused` to false. The function is going to be called `startTimer()`. In the function, add the line `timerIsPaused = false`. After that, a timer needs to be added, so the gist below shows that.

{% gist https://gist.github.com/appsbymw/08db81414f792e836dd819f7b0bfb918 %}

Now, I'm going to explain what's going on in lines 3 thourgh 5.

### 1. Make a new timer

This is where a new timer is actually made. I'm using a scheduled Timer so that every second something can be triggered. 

- `withTimeInterval` is used to specify how often, in seconds, each action inside the closure is executed. I have it set to 1, so that seconds is incremented each second.
- `repeats` needs to be set to true so that the code in the closure is ran every 1 second. If it is set to false, then the operations in the closure is only ran one time.

### 2. Check time to add

This is all the code to check when to increment seconds, minutes, and hours.

I chose to use the closure method of starting a new timer so that I didn't have to wrap the function in an objective-c caller.

Once the function is written, make sure to call it in the button. Here is what the Start button code should now look like.

{% gist https://gist.github.com/appsbymw/1790ada87fab17fbb52a28be0ca8d3ef %}

# Step 5: Stop the timer

It's time for another function to actually stop the timer. The function is going to be called `stopTimer()`. In this timer, we need to set `timerIsPaused` to false and kill the timer that is currently running. To kill the timer, we call the `invalidate()` function on the timer, which will not allow the timer to fire again. Here is what the function looks like.

{% gist https://gist.github.com/appsbymw/34c7949d8fbf0d5b30312bd1e220789a %}

Now, make sure to call the function when the Stop button is pressed.

Here is what `ContentView.swift` should look like at this point.

{% gist https://gist.github.com/appsbymw/51ad6dddfa5062387d47773a8f5e53eb %}

# Step 6: Reset the clock

This is the easiest function. It's going to set `hours`, `minutes`, and `seconds` back to 0.

{% gist https://gist.github.com/appsbymw/3a4a1b50014bffb09a6fa0ccdd0d56a3 %}

Now, call it when the reset button is pressed using `self.restartTimer()`.

# ✅ The count up timer is done!

Now the count up timer is done. You should be able to run the app, start the timer, stop the timer, and reset it.

![GIF OF WORKING APP](https://appsbymw.com/assets/images/2020-05-01/002_timer.gif)

The completed project can be cloned from [GitLab](https://gitlab.com/appsbymw/count-up-timer).

---

If you enjoy my posts, streams, and apps, consider encouraging my efforts.
- <a href="https://www.patreon.com/appsbymw" target="_blank"><button type="button" class="crayons-btn">Become a Patron</button></a>
- <a href="https://www.buymeacoffee.com/appsbymw" target="_blank"><button type="button" class="crayons-btn">Buy Me a Coffee</button></a>
- <a href="https://buttondown.email/appsByMW"><button type="button" class="crayons-btn">Subscribe to my Newsletter!</button></a>