I'm working to emulate the Activity Rings featured in Apple's Fitness app.
Here's a copy of what's in the swift file so far.
//
// ProgressRingPrototype.swift
// Nutrition
//
// Created by Derek Chestnut on 1/13/25.
//
import SwiftUI
struct ProgressRingPrototype: View {
@State var progress = 0.00
let size: CGSize
let thickness: CGFloat
var color: Color?
var gradientColors: [Color]?
var body: some View {
let color = color ?? .primary
ZStack {
RingPrototype(
size: self.size,
thickness: self.thickness,
color: color.opacity(0.2)
)
let gradient = AngularGradient(
colors: gradientColors ?? [.primary, .secondary],
center: .center
)
let style = StrokeStyle(
lineWidth: 32,
lineCap: .round
)
Circle()
.trim(from: 0, to: progress)
.stroke(gradient, style: style)
.rotationEffect(.degrees(-90))
.frame(width: size.width, height: size.height)
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
withAnimation(.easeInOut(duration: 1)) {
progress = 0.75
}
}
}
}
}
#Preview {
ZStack {
ProgressRingPrototype(
progress: 0.1,
size: CGSize(width: 256, height: 256),
thickness: CGFloat(32),
color: .primary
)
ProgressRingPrototype(
progress: 0.1,
size: CGSize(width: 190, height: 190),
thickness: CGFloat(32),
color: .primary
)
ProgressRingPrototype(
progress: 0.1,
size: CGSize(width: 124, height: 124),
thickness: CGFloat(32),
color: .primary
)
}
}
Here's a snapshot of the live preview.
I'm experiencing an issue where the trailing line cap generated by the stroke exceeds the start angle of the angular gradient, which creates an ugly artifact at 0 degrees.
Anyone have a solution to this problem?
Derek