Animation jumps when touching overlay during animation (BackdropExampleViewController)
Hi, I'm trying to animate other views in sync with the overlay transition. The BackdropExampleViewController example comes very close to what I want to do.
Everything works fine, but when I slide up the overlay, and then quickly slide it down again (before the slide-up animation has completed), the background transparency "jumps" a bit.
I've attached a video. It looks subtle here, but it becomes more annoying in my actual application. Do you have an idea how to fix this?
Best, Johannes animation.mov.zip
Hi @johannesd,
I don't see the "jumps" in the example. Note that the alpha of the backdropVC's view changes from 0 to 1 but the color is :
view.backgroundColor = UIColor.init(white: 0, alpha: 0.5)
So it actually changes from 0 to 0.5 only.
You can print the translationProgress in the transitionCoordinator to look for an issue:
transitionCoordinator.animate(alongsideTransition: { [weak self] context in
print("translation progress", context.translationProgress(), "isAnimated", context.isAnimated)
}, completion: nil)
Do you see something wrong?
Thanks for your reply! Hm, the numbers are correct, but I observe that the view is not updating property. I tried to make the example more obvious, but now it seems like the problem in my actual code is something else. What I want to do is adding an animation that is not linear to the overlay's movement: Some buttons in the map should fade out when the overlay is in maximized position (because there is not enough space for the buttons). Let's say, my notch positions are 20%, 50% 90%. The map button should fade out (i.e. its alpha should be adjusted from 1 to 0) when the overlay goes from 75% to 90%. Below 70%, it should be 1; above 90%, it should be 0.
If did that using code like
transitionCoordinator.animate(alongsideTransition: { [weak self] context in
button.alpha = 1 - (context.overallTranslationProgress() - 0.75) / 0.15
}, completion: nil)
This works while dragging the overlay. But when it animates to the final position, and the overlay is then dragged again, interrupting the animation, then the alpha value is updated after a delay for some reason.
So, I wonder if the proper way to do this is to use a different animation curve, that is 0 until 75% and goes up to 1 until 90%. Is there a way to add a separate animation to the transitionCoordinator that has a different curve?
Best, Johannes
I see, I would try to add my own animation and override the duration or the curve of the translation with those animation options:
UIViewAnimationOptionOverrideInheritedDuration
UIViewAnimationOptionOverrideInheritedCurve
like so:
transitionCoordinator.animate(alongsideTransition: { [weak self] context in
UIView.animate(withDuration: ..., delay: 0, options: .overrideInheritedDuration, animations: {
// ...
}, completion: nil)
}, completion: nil)
Does it do the trick?
After thinking more about it, I think a keyframe animation would be the right thing here.
UIView.animateKeyframes(withDuration: 0, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) {
self?.backdropViewController.debugView.alpha = 1
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
self?.backdropViewController.debugView.alpha = 1 - (context.translationProgress() - 0.5) * 2
}
}, completion: nil)
This works for the dragging part, but when the completion animations runs (after dropping the overlay), the keyframe animation seems to run independently from the overlay animation. Do you know how to sync those?
Best, Johannes