Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interactive transition weird blink on cancel

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

like image 877
Nicos Karalis Avatar asked Nov 09 '22 14:11

Nicos Karalis


1 Answers

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:YESin 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;
like image 173
wlixcc Avatar answered Nov 14 '22 23:11

wlixcc