SwiftUI: Animate Circles in List

Viewed 554

I've got the following code below which I use to create a List with a circle in each element.

My goal is to have a "circle fill animation" when the view is opend. In this case, the blue color should fill to the given percentage level. The Circles and List are working, however my animation is not kicked off when the List is loaded / the user accesses the view.

Any ideas what I'm doing wrong?

struct CircleListView: View {
    
    @State var percentage: CGFloat = 75
    
    var body: some View {
        
        List {
            ForEach(1..<10) { element in
                ZStack {
                    TrackCircle()
                    ProgressCircle(percentage: percentage)
                }
            }
        }
    }
}

struct ProgressCircle: View {
    var percentage: CGFloat
    
    var body: some View {
        ZStack {
            Circle()
                .trim(from: 0, to: (percentage * 0.01))
                .stroke(style: StrokeStyle(lineWidth: 8, lineCap: .round, lineJoin: .round))
                .fill(Color.blue)
                .rotationEffect(.degrees(270))
                .animation(.spring(response: 2.0, dampingFraction: 1.0, blendDuration: 1.0))
        }
    }
}

struct TrackCircle: View {
    var body: some View {
        ZStack {
            Circle()
                .stroke(style: StrokeStyle(lineWidth: 8))
                .fill(Color.red)
        }
    }
}

Many Thanks!

1 Answers

Animation starts when there is detected change of animatable property. Provided code is static - no run-time changes, so no animation.

Here is modified demo which activates animation (tested with Xcode 12.1 / iOS 14.1)

@State var percentage: CGFloat = 0     // << initial state

var body: some View {
    
    List {
        ForEach(1..<10) { element in
            ZStack {
                TrackCircle()
                ProgressCircle(percentage: percentage)
            }
        }
    }
    .onAppear { percentage = 75 }     // << changed state
}
Related