I have a ring animation that goes around a button when the button is pressed. In my mind it should stop when the button is pressed, but it has a very weird behavior. It seems to reverse instead of reverting back to 0. How can I get it to go back to zero after the second button click? Here is my code:
struct ContentView: View {
@State private var animationActive = false
let animation = Animation
.linear(duration: 10)
var body: some View {
ZStack {
GeometryReader {geo in
ZStack {
//Image("RecordButton")
Button {
animationActive.toggle()
} label: {
Image("RecordButton")
}
ring(for: Color.white)
.animation(animation, value: animationActive)
}
}.edgesIgnoringSafeArea(.all)
}
}
func ring(for color: Color) -> some View {
// Background ring
Circle()
.stroke(style: StrokeStyle(lineWidth: 20))
.frame(width: 250)
.foregroundStyle(.tertiary)
.overlay {
// Foreground ring
Circle()
.trim(from: 0, to: animationActive ? 1 : 0)
.stroke(color.gradient,
style: StrokeStyle(lineWidth: 20, lineCap: .round))
.frame(width: 250)
}
.rotationEffect(.degrees(-90))
}
}
You can change the .animation
modifier to use a 0-duration animation (no animation at all) depending on animationActive
:
.animation(animationActive ? animation : .linear(duration: 0), value: animationActive)
Note that the animation should be 0-duration when animationActive
is false, because this expression is evaluated after animationActive
has been toggled.
Alternatively, you can remove .animation
, and use withAnimation
instead:
Button {
withAnimation(animationActive ? .linear(duration: 0) : animation) {
animationActive.toggle()
}
} label: {
Image("RecordButton")
}