Skip to content

ProgressView (SwiftUI)

A SwiftUI guide for coding agents. Also covers progressview spinner, loading indicator ios, determinate progress bar, progressviewstyle protocol, fractioncompleted.

ProgressView shows ongoing work: a circular spinner when the duration is unknown, a linear bar when it is. A style protocol lets you redesign either completely.

Indeterminate and Determinate

A plain ProgressView() renders the circular activity indicator; ProgressView("Loading") adds a label. When the total is known, such as a file download with a known size, pass the value and total, and SwiftUI draws a linear bar at the computed fraction.

ProgressView()
ProgressView("Loading")
ProgressView(value: 250, total: 1000)

A ViewBuilder initializer customizes the label:

ProgressView {
  Text("Loading")
    .font(.title)
}

Custom Styles

Conform to ProgressViewStyle and implement makeBody(configuration:). The configuration exposes the label and fractionCompleted. An extension on the protocol gives the style dot syntax.

struct HorizontalProgressViewStyle: ProgressViewStyle {
  func makeBody(configuration: Configuration) -> some View {
    HStack(spacing: 8) {
      ProgressView()
        .progressViewStyle(.circular)
      configuration.label
    }
    .foregroundColor(.secondary)
  }
}

extension ProgressViewStyle where Self == HorizontalProgressViewStyle {
  static var horizontal: HorizontalProgressViewStyle { .init() }
}

ProgressView("Loading")
  .progressViewStyle(.horizontal)

For fully custom drawing, read configuration.fractionCompleted and render anything from text to an animated path. It is optional and is nil for indeterminate progress, so guard it before drawing.

struct CustomProgressViewStyle: ProgressViewStyle {
  func makeBody(configuration: Configuration) -> some View {
    VStack {
      if let value = configuration.fractionCompleted {
        CustomProgressView(value: value)
      }
      Text("Loading...")
    }
  }
}

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-mastering-progressview" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems