如何在UINavigationController中使用UIViewControllerAnimatedTransitioning?

时间:2014-04-05 17:17:05

标签: ios cocoa-touch ios7 xamarin.ios

将视图控制器推到UINavigationController时,如何获得自定义转换(iOS7)?我尝试在TransitioningDelegate和我推动的控制器上同时设置UINavigationController 这些方法永远不会被调用。

我发现的所有示例在模态呈现时都使用自定义转换。

4 个答案:

答案 0 :(得分:21)

@rounak有正确的想法,但有时无需从github下载就可以准备好代码。

以下是我采取的步骤:

  1. 使FromViewController.m符合UINavigationControllerDelegate。其他示例代码告诉您符合UIViewControllerTransitioningDelegate,但仅当您呈现 ToViewController时才会这样。

    @interface 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];
        }];
    }
    }
    
  4. 基本上,动画师是做重物的对象。当然,您可以将UINavigationControllerDelegate作为一个单独的对象,但这取决于您的应用程序的架构师。

答案 1 :(得分:4)

objc.io关于视图控制器转换的帖子专门用于推送和弹出视图控制器。 http://objc.io/issue-5/view-controller-transitions.html

我完全根据objc.io帖子完成了这个动画(http://i.imgur.com/1qEyMu3.gif)。

简而言之,你必须有一个实现UINavigationControllerDelegateUIViewControllerAnimatedTransitioning的类,其中包含返回正确的动画师和执行动画所需的方法。

答案 2 :(得分:2)

您可以查看我的演示项目,演示如何在UINavigationController中使用自定义过渡。请看https://github.com/Vaberer/BlurTransition

答案 3 :(得分:1)

编辑:刚刚意识到这可能无法回答你的问题。但它是另一种选择。

如果您正在使用故事板,则可以通过创建自定义segue来执行自定义转换。 在属性检查器中,将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];
}