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...")
}
}
}