Search code examples
macosanimationswiftuiprogress-bar

Animate circular ProgressView()


In my Swift application for macOS, I tried to add a ProgressView(), first linear, then circular. I can easily animate the linear one, but not the circular one.

demo

Here is my code:

var progressAction1 = 0.0

// linear
ProgressView(value: progressAction1ProgressView(value: progressAction1)
    .animation(.easeIn(duration: 1), value: progressAction1)
    // .padding(.horizontal, 20)

// circular
ProgressView(value: progressAction1)
    .animation(.easeIn(duration: 1), value: progressAction1)
    .progressViewStyle(.circular)
    // .padding(.horizontal, 20) 

Solution

  • It seems like circular progress views on macOS just simply doesn't support animations out of the box. Let's hope it does in a future macOS version.

    You can kind of make this work by creating an Animatable wrapper around ProgressView.

    struct AnimatableCircularProgressView<Value: BinaryFloatingPoint & VectorArithmetic>: View, Animatable {
        var progress: Value
        
        var animatableData: Value {
            get { progress }
            set { progress = newValue }
        }
        
        var body: some View {
            ProgressView(value: progress)
                .progressViewStyle(.circular)
        }
    }
    

    Usage:

    struct ContentView: View {
    
        @State private var progressAction1 = 0.0
        
        var body: some View {
            AnimatableCircularProgressView(progress: progressAction1)
                .animation(.easeIn(duration: 1), value: progressAction1)
            Button("Foo") {
                progressAction1 += 0.5
            }
        }
    }