Как использовать UIViewControllerAnimatedTransitioning с UINavigationController?

как я могу получить пользовательские переходы (iOS7) при нажатии контроллера вида на UINavigationController? Я попытался установить TransitioningDelegate обоих в UINavigationController а также на контроллере, который я нажимаю Методы никогда не вызываются.

все примеры, которые я нахожу, используют пользовательские переходы при представлении модально.

4 ответов


@rounak имеет правильную идею, но иногда это помогает иметь готовый код без необходимости загрузки с github.

вот шаги, которые я взял:

  1. сделайте свой FromViewController.м соответствует UINavigationControllerDelegate. Другой пример кода там говорит вам, чтобы соответствовать UIViewControllerTransitioningDelegate, но это только если вы представления в ToViewController.

    @интерфейс ViewController: UIViewController

  2. верните пользовательский объект аниматора перехода в методе обратного вызова делегата в FromViewController:

    - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC {
        TransitionAnimator *animator = [TransitionAnimator new];
        animator.presenting = (operation == UINavigationControllerOperationPush);
        return animator;
    }
    
  3. создайте свой пользовательский класс аниматора и вставьте эти примеры методов:

    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
        return 0.5f;
        }
    
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext     {
    // Grab the from and to view controllers from the context
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    // Set our ending frame. We'll modify this later if we have to
    CGRect endFrame = CGRectMake(80, 280, 160, 100);
    
    if (self.presenting) {
        fromViewController.view.userInteractionEnabled = NO;
    
        [transitionContext.containerView addSubview:fromViewController.view];
        [transitionContext.containerView addSubview:toViewController.view];
    
        CGRect startFrame = endFrame;
        startFrame.origin.x += 320;
    
        toViewController.view.frame = startFrame;
    
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
            toViewController.view.frame = endFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
    else {
        toViewController.view.userInteractionEnabled = YES;
    
        [transitionContext.containerView addSubview:toViewController.view];
        [transitionContext.containerView addSubview:fromViewController.view];
    
        endFrame.origin.x += 320;
    
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic;
            fromViewController.view.frame = endFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
    }
    

по сути, аниматор-это объект, выполняющий тяжелую работу. Конечно, вы можете сделать свой UINavigationControllerDelegate отдельным объектом, но это зависит от того, как ваш архитектор приложение.


objc.сообщение io на переходах контроллера вида специально предназначено для нажатия и выскакивания контроллеров вида. http://objc.io/issue-5/view-controller-transitions.html

Я сделал эту анимацию (http://i.imgur.com/1qEyMu3.gif) исключительно на основе objc.IO post.

короче говоря, у вас должен быть класс(ы), реализующий UINavigationControllerDelegate и UIViewControllerAnimatedTransitioning с необходимыми методами для возврата правильного аниматора и выполнения анимации.


вы можете посмотреть мой демо-проект, который демонстрирует использование пользовательских переходов в UINavigationController. Посмотрите наhttps://github.com/Vaberer/BlurTransition.


EDIT: просто понял, что это может не ответить на ваш вопрос. Но это альтернатива.

если вы используете раскадровку, вы можете сделать пользовательский переход, создав пользовательский сегмент. В инспекторе атрибутов измените имя класса segue на свой пользовательский класс перехода, например MySegue. Затем создайте MySegue класс и реализовать -(void)perform метод для выполнения вашего перехода.

- (void) perform{
      UIViewController *source = self.sourceViewController;
      UIViewController *destination = self.destinationViewController;
      [UIView transitionFromView:source.view
                          toView:destination.view
                        duration:0.50f
                         options:UIViewAnimationOptionTransitionFlipFromTop
                      completion:nil];
}