Created
September 14, 2020 16:05
-
-
Save BetterProgramming/5fd193a119fdc7a750465bcfaf373c13 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// An animatable modifier that is used for observing animations for a given animatable value. | |
struct AnimationCompletionObserverModifier<Value>: AnimatableModifier where Value: VectorArithmetic { | |
/// While animating, SwiftUI changes the old input value to the new target value using this property. This value is set to the old value until the animation completes. | |
var animatableData: Value { | |
didSet { | |
notifyCompletionIfFinished() | |
} | |
} | |
/// The target value for which we're observing. This value is directly set once the animation starts. During animation, `animatableData` will hold the oldValue and is only updated to the target value once the animation completes. | |
private var targetValue: Value | |
/// The completion callback which is called once the animation completes. | |
private var completion: () -> Void | |
init(observedValue: Value, completion: @escaping () -> Void) { | |
self.completion = completion | |
self.animatableData = observedValue | |
targetValue = observedValue | |
} | |
/// Verifies whether the current animation is finished and calls the completion callback if true. | |
private func notifyCompletionIfFinished() { | |
guard animatableData == targetValue else { return } | |
/// Dispatching is needed to take the next runloop for the completion callback. | |
/// This prevents errors like "Modifying state during view update, this will cause undefined behavior." | |
DispatchQueue.main.async { | |
self.completion() | |
} | |
} | |
func body(content: Content) -> some View { | |
/// We're not really modifying the view so we can directly return the original input value. | |
return content | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment