Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 7 use custom interactive transitions only some of the time

So I have a UINavigationController, with Controller A as the root controller.

When I want to push Controller B on top, I want to use a custom animated transition and a custom interactive transition. This works fine.

When I want to push Controller C on top, I want to fall back to the default push/pop transitions that comes with UINavigationController. To make this happen I return nil for

navigationController:animationControllerForOperation:fromViewController:toViewController:

however if you return nil, then

navigationController:interactionControllerForAnimationController:

will never be called and the default "pan from left edge" pop interactive transition doesn't work.

Is there a way to return the default push/pop animation controller and interaction controller? (Are there concrete implementations of id<UIViewControllerAnimatedTransitioning> and id<UIViewControllerInteractiveTransitioning>?)

Or some other way?

like image 603
just.jimmy Avatar asked Nov 21 '13 06:11

just.jimmy


1 Answers

You should set NavigationController's interactivePopGestureRecognizer delegate to self and then handle its behavior in -gestureRecognizerShouldBegin:

That is, when you want the built-in pop gesture to fire, you must return YES from this method. The same goes for your custom gestures - you have to figure out which recognizer you are dealing with.

- (void)setup
{
    self.interactiveGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleTransitionGesture:)];
    self.interactiveGestureRecognizer.delegate = self;
    [self.navigationController.view addGestureRecognizer:self.interactiveGestureRecognizer];

    self.navigationController.interactivePopGestureRecognizer.delegate = self;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    // Don't handle gestures if navigation controller is still animating a transition
    if ([self.navigationController.transitionCoordinator isAnimated])
        return NO;

    if (self.navigationController.viewControllers.count < 2)
        return NO;

    UIViewController *fromVC = self.navigationController.viewControllers[self.navigationController.viewControllers.count-1];
    UIViewController *toVC = self.navigationController.viewControllers[self.navigationController.viewControllers.count-2];

    if ([fromVC isKindOfClass:[ViewControllerB class]] && [toVC isKindOfClass:[ViewControllerA class]])
    {
        if (gestureRecognizer == self.interactiveGestureRecognizer)
            return YES;
    }
    else if (gestureRecognizer == self.navigationController.interactivePopGestureRecognizer)
    {
        return YES;
    }

    return NO;
}

You can check out a sample project for your scenario. Transitions between view controllers A and B are custom animated, with custom B->A pop gesture. Transitions between view controllers B and C are default, with built-in navigation controller's pop gesture.

Hope this helps!

like image 76
maxkonovalov Avatar answered Oct 21 '22 07:10

maxkonovalov