Animate a Progress Bar in SwiftUI
Written by Team Kodeco
A progress bar is a common UI element used to indicate how close a task or operation is to completion. Animating the progress bar not only enhances the user experience but also makes it more visually appealing. In this cookbook entry, you will learn how to animate a progress bar in SwiftUI.
To animate a progress bar, you can use the built-in Animation
modifier in SwiftUI. The Animation
modifier allows you to animate the changes to a view over a defined duration. Here’s an example of animating a progress bar:
import SwiftUI
import Combine
struct ContentView: View {
@State private var progress: CGFloat = 0.0
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
var body: some View {
ZStack(alignment: .leading) {
Rectangle()
.frame(width: 300, height: 20)
.opacity(0.3)
.foregroundColor(.gray)
Rectangle()
.frame(width: progress * 300, height: 20)
.foregroundColor(.green)
.animation(.easeInOut, value: progress)
}
.onReceive(timer) { _ in
if progress < 1.0 {
progress += 0.01
}
}
}
}
Your preview should look like this:
This code creates a progress bar and updates it over time using a timer.
Here’s a detailed explanation:
-
@State private var progress = 0.0
defines a state variable namedprogress
. State variables in SwiftUI are sources of truth for data in your app. When you update the state, SwiftUI knows it needs to rerender the views that depend on that piece of state. -
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
creates a timer that fires every 0.1 seconds on the main queue. It uses thepublish
function to create a timer publisher that emits the current date on the specified interval. Theautoconnect()
function starts the timer. Remember to haveimport Combine
at the top of your file to use theautoconnect()
publisher. - Inside the
body
property, two rectangles are drawn. The first rectangle is a gray static bar that serves as the background. The second rectangle is a green bar that represents the progress. Its width is proportional to theprogress
variable. -
.animation(.easeInOut, value: progress)
makes changes toprogress
animate smoothly. The.easeInOut
means the rate of change starts slow, accelerates and then slows down at the end. -
.onReceive(timer) { _ in ... }
is an event handler for the timer. Every time the timer fires (every 0.1 seconds), the code inside this block is run. The_ in
indicates that the timer’s output (which is the current time) is ignored. - Inside the timer’s event handler, it checks if
progress
is less than 1.0. If it is,progress
is increased by 0.01. Whenprogress
reaches 1.0, the green bar is fully extended, and the progress bar is complete.
In conclusion, SwiftUI provides a simple and effective way of animating progress bars using the animation
modifier. By animating the progress bar, you can create a better user experience that is both informative and visually appealing.