Chapters

Hide chapters

SwiftUI Cookbook

Live Edition · iOS 16.4 · Swift 5.8.1 · Xcode 14.3.1

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:

You can use a Rectangle view with an animation modifier to create an animated progress bar.
You can use a Rectangle view with an animation modifier to create an animated progress bar.

This code creates a progress bar and updates it over time using a timer.

Here’s a detailed explanation:

  1. @State private var progress = 0.0 defines a state variable named progress. 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.
  2. 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 the publish function to create a timer publisher that emits the current date on the specified interval. The autoconnect() function starts the timer. Remember to have import Combine at the top of your file to use the autoconnect() publisher.
  3. 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 the progress variable.
  4. .animation(.easeInOut, value: progress) makes changes to progress animate smoothly. The .easeInOut means the rate of change starts slow, accelerates and then slows down at the end.
  5. .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.
  6. Inside the timer’s event handler, it checks if progress is less than 1.0. If it is, progress is increased by 0.01. When progress 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.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.