I'm trying to figure out how to detect that an animation has completed in SwiftUI, to be specific: a Spring() animation. My first thought was to use a GeometryReader to detect when the Circle in the example below reaches the point of origin (offset = .zero), however there is one caveat to this approach: the Spring() animation goes a little bit beyond the point where it should end and then bounces back. So the "end of the animation" would be triggered before the animation has finished.
I did some research and found another approach : SwiftUI withAnimation completion callback. However, in this solution the offset of the animated object is compared to the point of origin so it's the same problem as described above.
I could use a timer but that wouldn't be an elegant solution since the duration of the Spring() animation dynamically changes depending from where it started, so that's not the way.
In the example below, I would like that the circle gets green after the animation has finished.
Is there a way to solve this issue? Thanks for helping!
struct ContentView: View {
@State var offset: CGSize = .zero
@State var animationRunning = false
var body: some View {
VStack {
Circle()
.foregroundColor(self.animationRunning ? .red : .green)
.frame(width: 200, height: 200)
.offset(self.offset)
.gesture(
DragGesture()
.onChanged{ gesture in
self.offset = gesture.translation
}
.onEnded{_ in
self.animationRunning = true
withAnimation(.spring()){
self.offset = .zero
}
})
Spacer()
}
}
}