Reputation: 3773
I am following this tutorial to learn how can I make interactive transitions for UIViewControllers.
Everything works fine but I found some flickering.
The first flicker I found happens when you drag the screen from right to left. This is because the pan gesture will recognize every drag and run the panned(_:)
method and will pop or perform a segue to change controllers. I fixed id adding the delegate method gestureRecognizerShouldBegin(_:)
.
This ensures me that if a drag from right to left is made the gesture is never started (.Begin
).
But now I have a different problem. If I drag from left to right (as intended) but, without interrupting the drag, change direction to right to left the transition should be canceled. In this event I can see a brief flicker with the new controller before the old controller is presented again.
What can I do to gracefully cancel the interactive animation?
This is a video trying to show the problem. I could not found a way to slow down this animation so it's very fast.
EDIT
I've tried with 2 different approaches.
This one uses CABasicAnimation
to animate the transition. And this one uses animateWithDuration(_:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)
Both of them still flicker whenever I call cancelInteractiveTransition
Upvotes: 5
Views: 1114
Reputation: 1492
This is my way to solve the problem:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
[UIView animateWithDuration:[self transitionDuration:transitionContext]
delay:self.interactive?[self transitionDuration:transitionContext]:0 // If zero, the animation briefly flashes in iOS 11.
options:option
animations:^{
} completion:^(BOOL finished) {
}];
}
the most import thing is delay animation in interactive transition
see code below:I found if we call dismissViewControllerAnimated:YES
in UIGestureRecognizerStateBegan
, animation immediately start if we don't delay animation。 Then, in UIGestureRecognizerStateChanged
, updateInteractiveTransition:progress
will bring view to "progress position"。It seems a flash
switch (sender.state) {
case UIGestureRecognizerStateBegan:
_interactive = YES;
[viewcontroller dismissViewControllerAnimated:YES completion:nil];
break;
case UIGestureRecognizerStateChanged:
[self updateInteractiveTransition:progress];
break;
case UIGestureRecognizerStateEnded:
{
_interactive = NO;
if (shouleFinish) {
[self finishInteractiveTransition];
} else {
[self cancelInteractiveTransition];
}
}
break;
case UIGestureRecognizerStateCancelled:
_interactive = NO;
[self cancelInteractiveTransition];
break;
default:
break;
Upvotes: 1