History
Loading...
Loading...
September 23, 2025
ProgressView with indeterminate state for unknown durations, but switch to determinate with actual progress values when available. You can customize appearance with .progressViewStyle() and .tint() modifiers for brand consistency.Custom ProgressView styles provide consistent loading indicators across your app while supporting both determinate and indeterminate states. The style automatically adapts based on whether progress values are provided.
struct CustomProgressViewStyle: ProgressViewStyle {
func makeBody(configuration: Configuration) -> some View {
VStack {
ZStack {
Circle()
.stroke(Color.gray.opacity(0.3), lineWidth: 4)
Circle()
.trim(from: 0, to: configuration.fractionCompleted ?? 0)
.stroke(Color.blue, style: StrokeStyle(lineWidth: 4, lineCap: .round))
.rotationEffect(.degrees(-90))
}
.frame(width: 40, height: 40)
if let label = configuration.label {
label
.font(.caption)
.foregroundColor(.secondary)
}
}
}
}
struct LoadingView: View {
@State private var progress = 0.0
var body: some View {
VStack(spacing: 20) {
ProgressView("Loading...", value: progress, total: 1.0)
.progressViewStyle(CustomProgressViewStyle())
ProgressView("Processing...")
.progressViewStyle(CustomProgressViewStyle())
}
.onAppear {
simulateProgress()
}
}
private func simulateProgress() {
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
progress += 0.05
if progress >= 1.0 {
timer.invalidate()
}
}
}
}This approach ensures visual consistency, reduces code duplication, and provides flexibility for different loading scenarios. Custom styles make your app feel more polished and maintain brand identity throughout the user experience.