Make a countdown timer in SwiftUI
In this tutorial, we’ll learn how to make a countdown timer in SwiftUI. Whenever there is some task that we have to perform repeatedly after some specific time interval we use the timer. It comes from the swift foundation framework. So, we’ll use a timer in this blog to achieve this functionality of countdown times.
What this blog will cover:
- Timer.
- onReceive modifier.
CountDown Timer in SwiftUI
Let’s see how we can make a countdown timer in SwiftUI using the timer.
Syntax:
for declaring the timer
var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
- The timer is set to run after every 1 sec
- It’s running on the main thread since we are updating the UI so we need to run it on the main thread
- The auto-connect will start the timer automatically when we listen to it.
For canceling the timer
timer.upstream.connect().cancel()
Let’s see how we’ll use it in the code
struct ContentView:View{ @State var timeRemaining: Int = 5 @State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() var body: some View { VStack(spacing: 30){ Text("Timer: \(timeRemaining)").bold().fontWeight(.heavy) .onReceive(timer){_ in if timeRemaining>0{ // if timeremaining is greater than zero subtract 1 timeRemaining -= 1 } else { //else reset it to 5 if its equal to 0. this will save it from a negative num timeRemaining = 5 } } } } }
- onReceive is the modifier that listens to the timer. Since the timer is set auto connect so as soon as the textView Appears on the screen its onReceive modifier will listen to the timer, starts the countdown, and performs the action that is defined in its closure.
- The closure is the ending part of the onReciece modifier inside the curly braces.
In the closure, there is a simple condition that checks the timeRemaining
property which is set to 5 initially and subtracts 1 from it after every 1 sec. And if the timeRemaining
value is equal to zero it resets it to 5, just so it won’t have a negative value, and it again starts the countdown from 5 to 0.
Timer with pause and resume button swiftUI
We are adding a button that can trigger the timer and cancel it whenever the user wants. And we can do so just by using a single line. Let’s see how simple it is.
//Make a countdown times in Swift struct ContentView:View{ @State var pauseResumeBtn = "Pause" @State var timeRemaining: Int = 5 @State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() var body: some View { VStack(spacing: 30){ Text("Timer: \(timeRemaining)") .fontWeight(.heavy) .font(.system(size: 36)) .onReceive(timer){_ in if timeRemaining>0{ // if timeremaining is greater than zero subtract 1 timeRemaining -= 1 } else { //else reset it to 5 if its equal to 0. this will save it from a negative num timeRemaining = 5 } } Button(pauseResumeBtn){ if pauseResumeBtn == "Resume"{ // For cancelling the timer pauseResumeBtn = "Pause" timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() } else{ //Resume the timer pauseResumeBtn = "Resume" self.timer.upstream.connect().cancel() } } .frame(width: 120,height: 30) .foregroundColor(.white) .background(Color.mint) .fontWeight(.bold) .cornerRadius(20) } } }
So the button is checking the condition of whether the button text is set to Resume. If it is then change the button text to pause and restart the timer.
and else the clause of the condition will run when the button text is set to pause. The else block will stop the timer and change the button text back to Resume.
Leave a Reply