This article is the 18th day article of Diverse Advent Calendar 2020. I made some progresses in my work, so I will introduce them. Please use it when you make a progress with a similar design!
I have a sample of this article on GitHub. ↓ Click here if you want to see the actual movement https://github.com/Masataka-n/SwiftUIProgress
Ring
struct RingProgressView: View {
    var value: CGFloat
    var lineWidth: CGFloat = 6.0
    var outerRingColor: Color = Color.black.opacity(0.08)
    var innerRingColor: Color = Color.orange
    var body: some View {
        ZStack {
            Circle()
                .stroke(lineWidth: self.lineWidth)
                .foregroundColor(self.outerRingColor)
            Circle()
                .trim(from: 0.0, to: CGFloat(min(self.value, 1.0)))
                .stroke(
                    style: StrokeStyle(
                        lineWidth: self.lineWidth,
                        lineCap: .square, //If you want to round the corners of the progress.round
                        lineJoin: .round
                    )
                )
                .foregroundColor(self.innerRingColor)
                .rotationEffect(.degrees(-90.0))
        }
        .padding(.all, self.lineWidth / 2)
    }
}
@State var value: CGFloat = 0.0
 var body: some View {
    RingProgressView(value: value)
        .frame(width: 150, height: 150)
        .onAppear {
            withAnimation(.linear(duration: 5)) {
                self.value = 1.0
            }
        }        
}

Pie
I inherited Shape and made something called Pie Shape.
If you create your own Shape, you will need to override animatableData as the animation will not be applied.
struct PieProgressView: View {
    var value: CGFloat
    var body: some View {
        ZStack {
            Circle()
                .fill(Color.black.opacity(0.08))
            PieShape(progress: value)
                .fill(Color.orange)
                .rotationEffect(.degrees(-90))
        }
    }
}
struct PieShape: Shape {
    var value: CGFloat
    var animatableData: CGFloat {
        get { value }
        set { value = newValue }
    }
    func path(in rect: CGRect) -> Path {
        Path { path in
            let center = CGPoint(x: rect.midX, y: rect.midY)
            path.move(to: center)
            path.addArc(
                center: center,
                radius: rect.width / 2,
                startAngle: .degrees(0),
                endAngle: .degrees(Double(360 * value)),
                clockwise: false
            )
            path.closeSubpath()
        }
    }
}
@State var value: CGFloat = 0.0
var body: some View {
    PieProgressView(value: value)
        .frame(width: 150, height: 150)
        .onAppear {
            withAnimation(.linear(duration: 5)) {
                self.value = 1.0
            }
        } 
}

Square
It is realized by stacking two Rectangles and changing the width of the above Rectangle according to the value. We call it Square, but you can also specify cornerRadius to round the corners.
struct SquareProgressView: View {
    var value: CGFloat
    var baseColor: Color = Color.black.opacity(0.08)
    var progressColor: Color = Color.orange
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .trailing) {
                ZStack(alignment: .leading) {
                    Rectangle()
                        .fill(self.baseColor)
                    Rectangle()
                        .fill(Color.progressColor)
                        .frame(minWidth: 0, idealWidth:self.getProgressBarWidth(geometry: geometry),
                               maxWidth: self.getProgressBarWidth(geometry: geometry))
                }
            }
        }
    }
    func getProgressBarWidth(geometry:GeometryProxy) -> CGFloat {
        let frame = geometry.frame(in: .global)
        return frame.size.width * value
    }
}
@State var value: CGFloat = 0.0
var body: some View {
    SquareProgressView(value: value)
        .frame(height: 20)
        //.cornerRadius(10)Rounded corners are also possible
        .onAppear {
            withAnimation(.linear(duration: 5)) {
                self.value = 1.0
            }
        } 
}

This time, I introduced three progresses I created. I think that you can basically use it with copy and paste, so please use it.
Recommended Posts