TechnologiesSwiftUIControls and Style Configurations

ProgressViewStyleConfiguration struct

iOSmacOStvOSwatchOSvisionOSiOS 14.0+✓ renders

The properties of a progress view instance.

How it works

ProgressViewStyleConfiguration carries the properties of a progress view into the style that draws it. When you create a custom ProgressViewStyle, SwiftUI hands your makeBody(configuration:) method one of these values describing the progress view it should render — its label and its current completion. Reach for it whenever the built-in progress styles aren't enough and you want full control over how progress is presented while still letting each ProgressView supply its own content and value.

  1. Receive the configuration in makeBody(configuration:)

    A custom style conforms to ProgressViewStyle and implements makeBody(configuration:), which SwiftUI calls once per progress view. The single parameter is a ProgressViewStyleConfiguration that stands in for the view being styled. In the example, BarStyle declares func makeBody(configuration: ProgressViewStyleConfiguration) -> some View and returns a VStack built entirely from that configuration.

  2. Place the view's content with configuration.label

    The label property exposes the content the progress view was given — a type-erased view you position wherever your layout calls for it, rather than supplying your own text. The example renders configuration.label at the top of the stack and styles it with .font(.headline), so each ProgressView keeps its own label while the style controls placement.

  3. Read progress from configuration.fractionCompleted

    fractionCompleted is an optional Double between 0 and 1 that reports how far along the work is, or nil for indeterminate progress. The example feeds it straight into ProgressView(value: configuration.fractionCompleted) to draw the bar, and because it is optional it uses if let fraction = configuration.fractionCompleted to show a percentage only when a definite value exists.

  4. Compose your own presentation around those members

    Because makeBody returns some View, you assemble the label and fraction into any layout and decorate it freely. The example wraps them in a VStack, tints the inner bar with .tint(.green), and derives a caption with Text("\(Int(fraction * 100))%") — all driven by the configuration rather than hard-coded content.

  5. Attach the style with progressViewStyle()

    Your custom style takes effect when applied to a progress view via the progressViewStyle(_:) modifier, which is also what triggers SwiftUI to build and pass the configuration. The example creates a ProgressView(value: 0.65) with a Label("Downloading", systemImage: "arrow.down.circle") and applies .progressViewStyle(BarStyle()), so 0.65 arrives as fractionCompleted and the label arrives as configuration.label.

Try it — Change ProgressView(value: 0.65) to ProgressView() with no value, and the if-let on configuration.fractionCompleted will fail, showing how the configuration reports indeterminate progress as nil.

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.

ProgressViewStyleConfiguration.swift
struct ProgressViewStyleConfigurationDemo: View {
    struct BarStyle: ProgressViewStyle {
        func makeBody(configuration: ProgressViewStyleConfiguration) -> some View {
            VStack(alignment: .leading, spacing: 6) {
                configuration.label
                    .font(.headline)
                ProgressView(value: configuration.fractionCompleted)
                    .tint(.green)
                if let fraction = configuration.fractionCompleted {
                    Text("\(Int(fraction * 100))%")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
            }
        }
    }

    var body: some View {
        ProgressView(value: 0.65) {
            Label("Downloading", systemImage: "arrow.down.circle")
        }
        .progressViewStyle(BarStyle())
        .padding()
    }
}
Live preview
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →