Here is possible approach (based on AnimatableModifier
). Actually it demonstrates how current animation end can be detected, and performed something - in this case, for your scaling scenario, just initiate reversing.
Tested with Xcode 11.4 / iOS 13.4
Simplified & modified your example
struct TestReversingScaleAnimation: View {
@State var scaleImage : CGFloat = 1
var body: some View {
VStack {
Button("Start animation") {
self.scaleImage = 0.01 // initiate animation
}
Image(systemName: "circle.fill")
.modifier(ReversingScale(to: scaleImage) {
self.scaleImage = 1 // reverse set
})
.animation(.default) // now can be implicit
}
}
}
Actually, show-maker here... important comments inline.
struct ReversingScale: AnimatableModifier {
var value: CGFloat
private var target: CGFloat
private var onEnded: () -> ()
init(to value: CGFloat, onEnded: @escaping () -> () = {}) {
self.target = value
self.value = value
self.onEnded = onEnded // << callback
}
var animatableData: CGFloat {
get { value }
set { value = newValue
// newValue here is interpolating by engine, so changing
// from previous to initially set, so when they got equal
// animation ended
if newValue == target {
onEnded()
}
}
}
func body(content: Content) -> some View {
content.scaleEffect(value)
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…