TechnologiesSwiftUI

ProgressView struct

iOSmacOStvOSwatchOSvisionOSiOS 14.0+✓ renders

A view that shows the progress toward completion of a task.

How it works

A ProgressView shows the progress of a task over time. Use it to reassure people that work is underway — whether the task has a known endpoint, such as a file download, or an open-ended one, such as waiting on a network request. By default the view renders an indeterminate spinner, but supplying a fractional value turns it into a determinate bar that fills as the work completes, so you reach for ProgressView wherever a view needs to communicate that something is happening.

  1. Show indeterminate progress with ProgressView()

    Calling the no-argument initializer creates an indeterminate progress indicator, typically an animated spinner, for tasks whose completion can't be measured. Use it when you only need to signal that work is in flight. In the example, ProgressView() produces this spinning form.

  2. Add a label

    Several initializers accept a label that describes the task to the person waiting. The string overload, ProgressView("Loading…"), builds the label for you, while other initializers take a label view builder — here Text("Downloading") — so the indicator carries a caption explaining what it represents.

  3. Report determinate progress with value:

    Pass a fractional completion to the value: parameter and ProgressView becomes determinate, drawing a bar that fills from empty to full. ProgressView(value: 0.6) reports the task as 60 percent complete; the value is interpreted against a total that defaults to 1.0, which you can override with the total: parameter.

  4. Choose a presentation with progressViewStyle(_:)

    The progressViewStyle(_:) modifier selects how the indicator is drawn, letting one ProgressView render as a spinner or a horizontal bar without changing the surrounding code. Applying .progressViewStyle(.linear) forces the linear bar style; .circular is the other built-in choice, and the style also propagates to ProgressViews nested within the modified view.

Try it — Change ProgressView(value: 0.6) to ProgressView(value: 1.0) to see the determinate bar fill completely.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

ProgressView.swift
struct ProgressViewDemo: View {
    var body: some View {
        VStack(spacing: 24) {
            ProgressView()
            ProgressView("Loading…")
            ProgressView(value: 0.6) {
                Text("Downloading")
            }
            .progressViewStyle(.linear)
        }
        .padding()
    }
}
Live preview
Loading…
Loading…
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →