I'm trying to smoothly animate the change of the length of an arc using the .animate()
method of a binding, but the animation does not occur - it just changes suddenly. Here's a minimal example - what am I doing wrong?
I'm using WatchOS.
import SwiftUI
struct TestAnimation: View {
@State var value: Float = 0.2
var body: some View {
VStack {
Arc(value: $value)
Button(action: { self.value = 0.1 }) {
Text("Increment")
}
}
}
}
struct Arc: View {
var value: Binding<Float>
var body: some View {
ArcShape(value: value.animation(.easeOut(duration:2)))
.stroke(lineWidth: 3)
}
}
struct ArcShape : Shape {
var value: Binding<Float>
func path(in rect: CGRect) -> Path {
var p = Path()
let arcDegrees: Double = max(360.0 * Double(value.wrappedValue), 2.0)
let endAngle = -90.0 arcDegrees
p.addArc(center: CGPoint(x: rect.midX, y:rect.midY), radius: rect.height / 2, startAngle: .degrees(-90), endAngle: .degrees(endAngle), clockwise: false)
return p
}
}
CodePudding user response:
We need animatable data in shape and actually do not need binding but animation directly on Arc.
Tested with Xcode 13.4 / watchOS 8.5
Here is main part of fixed code:
struct Arc: View {
var body: some View {
ArcShape(value: value) // << here !!
.stroke(lineWidth: 3)
.animation(.easeOut(duration:2), value: value)
}
// ...
struct ArcShape : Shape {
var animatableData: CGFloat {
get { value }
set { value = newValue }
}
// ...