CircularProgress is small and flexible implementation of circular progress view in SwiftUI. It allows to add pretty and customizable circular progress loaders into your application .
- Simple just add
CircularProgress()
to your view hierarchy and you will get smooth and animatable progress view. - Flexible implementation allow to define custom style and and content inside the circle.
- Lightwheight the package is small and won't introduce any overheds to SPM resolve process, no 3rd party dependencies.
struct SimpleExampleView: View {
@State
var progress: Double = 0
let lineWidth: CGFloat
var body: some View {
CircularProgress(lineWidth: lineWidth, state: progress)
.onTimer { progress += 0.34 }
}
}
struct InteractiveExampleView: View {
@State
var progress = CircularProgressState.inProgress(0)
let lineWidth: CGFloat
var body: some View {
CircularProgress(lineWidth: lineWidth, state: progress)
.progressStyle(.interactive)
.onTimer {
progress = if progress.rawValue + 0.34 >= 1 { Bool.random() ? .succeeded : .failed }
else { .inProgress(progress.rawValue + 0.34) }
}
}
}
struct RotatingExampleView: View {
@State
var progress: Double = 0
let lineWidth: CGFloat
var body: some View {
CircularProgress(lineWidth: lineWidth, state: progress)
.progressStyle(.rotating)
.onTimer(1) { progress += 0.25 }
}
}
struct CustomExampleView: View {
@State
var progress: CustomState = .inProgress(0)
let lineWidth: CGFloat
var body: some View {
CircularProgress(lineWidth: lineWidth, state: progress)
.progressStyle(.custom)
.onTimer(0.5) {
progress = if progress.rawValue + 0.34 >= 1 { .finished }
else { .inProgress(progress.rawValue + 0.34) }
}
}
}
enum CustomState {
case inProgress(Double)
case finished
}
extension CustomState: RawRepresentable {
public var rawValue: Double {
switch self {
case let .inProgress(progress): progress
case .finished: 1.0 }
}
public init?(rawValue: Double) {
self = .inProgress(rawValue)
}
}
struct CustomCircularProgressStyle: CircularProgressStyle {
func makeBody(configuration: CircularProgressStyleConfiguration<CustomState>) -> some View {
CircularProgress(
lineWidth: configuration.lineWidth,
state: configuration.state,
color: { state in
switch state {
case .finished: .pink
case .inProgress: .white }
}
) { state in
switch state {
case .finished: Text("🎉").font(.largeTitle).bold()
case .inProgress: Text(String("\(state.rawValue * 100)")) }
}
}
}
extension CircularProgressStyle where Self == CustomCircularProgressStyle {
static var custom: CustomCircularProgressStyle { CustomCircularProgressStyle() }
}
circular_progress_examples.mov
- iOS 14.0+
- macOS 11.0+
- watchOS 7.0+
- tvOS 14.0+
SwiftPM
.package(url: "https://github.com/aleksproger/circular-progress.git", .upToNextMajor(from: "1.1.0"))
Bazel
git_repository(
name = "circular-progress",
branch = "1.1.0",
remote = "https://github.com/aleksproger/circular-progress.git",
repo_mapping = {},
)