How to use UIViewControllerAnimatedTransitioning with UINavigationController?

前端 未结 4 1943
野性不改
野性不改 2020-12-08 06:00

How can I get custom transitions (iOS7) when pushing a view controller onto UINavigationController? I tried setting the TransitioningDelegate both

相关标签:
4条回答
  • 2020-12-08 06:37

    objc.io's post on view controller transitions are specifically for pushing and popping view controllers. http://objc.io/issue-5/view-controller-transitions.html

    I've done this animation (http://i.imgur.com/1qEyMu3.gif) solely based on the objc.io post.

    In short you have to have a class(es) implementing UINavigationControllerDelegate, and UIViewControllerAnimatedTransitioning with the required methods for returning the correct animator, and performing the animations.

    0 讨论(0)
  • 2020-12-08 06:48

    EDIT: Just realised this might not answer your question. But it is an alternative.

    If you're using a storyboard you can do a custom transition by creating a custom segue. In the attributes inspector change the segue class name to your custom transition class e.g. MySegue. Then create the MySegue class and implement the -(void)perform method to perform your transition.

    - (void) perform{
          UIViewController *source = self.sourceViewController;
          UIViewController *destination = self.destinationViewController;
          [UIView transitionFromView:source.view
                              toView:destination.view
                            duration:0.50f
                             options:UIViewAnimationOptionTransitionFlipFromTop
                          completion:nil];
    }
    
    0 讨论(0)
  • 2020-12-08 06:49

    @rounak has the right idea, but sometimes it helps to have code ready without having to download from github.

    Here are the steps that I took:

    1. Make your FromViewController.m conform to UINavigationControllerDelegate. Other sample code out there tells you to conform to UIViewControllerTransitioningDelegate, but that's only if you're presenting the ToViewController.

      @interface ViewController : UIViewController

    2. Return your custom transition animator object in the delegate callback method in 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. Create your custom animator class and paste these sample methods:

      - (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];
          }];
      }
      }
      

    Essentially, the animator is the object doing the heavy lifting. Of course, you can make your UINavigationControllerDelegate be a separate object, but that depends on how your architect your app.

    0 讨论(0)
  • 2020-12-08 06:56

    You can look at my demo project which demonstrates using custom transitions in UINavigationController. Look at https://github.com/Vaberer/BlurTransition.

    0 讨论(0)
提交回复
热议问题