Restore pre-iOS7 UINavigationController pushViewController animation

前端 未结 10 2115
终归单人心
终归单人心 2020-11-30 21:14

So. Just started transitioning my IOS code to IOS7, and ran into a bit of problem.

I\'ve got a UINavigationController, which has child ViewControllers a

相关标签:
10条回答
  • 2020-11-30 22:09

    Swift 5 implementation of Arne's answer:

    extension UINavigationController {
      func pushViewControllerLegacyTransition(_ viewController: UIViewController) {
        let transition = CATransition()
        transition.duration = 0.25
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        transition.type = .push
        transition.subtype = .fromRight
        view.layer.add(transition, forKey: nil)
        pushViewController(viewController, animated: false)
      }
    
      func popViewControllerLegacyTransition() {
        let transition = CATransition()
        transition.duration = 0.25
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        transition.type = .push
        transition.subtype = .fromLeft
        view.layer.add(transition, forKey: nil)
        popViewController(animated: false)
      }
    }
    
    0 讨论(0)
  • 2020-11-30 22:12

    I have the same problem with clear background colors and crappy animations, so I create custom transitioning for ViewController with new iOS7 API. All you need is simply set a delegate for your navigation controller:

    // NavigationController does not retain delegate, so you should hold it.
    self.navigationController.delegate = self.navigationTransitioningDelegate;
    

    Just add this files into your project: MGNavigationTransitioningDelegate.

    0 讨论(0)
  • 2020-11-30 22:14

    First of, I'm not using Storyboard. I tried using UINavigationController+Retro. For some reason, the UINavigationController is having a hard time releasing the UIViewController at the top of the stack. Here's the solution that works for me using iOS 7 custom transition.

    1. Set delegate to self.

      navigationController.delegate = self;
      
    2. Declare this UINavigationControllerDelegate.

      - (id<UIViewControllerAnimatedTransitioning>)navigationController (UINavigationController *)navigationController 
      animationControllerForOperation:(UINavigationControllerOperation)operation
      fromViewController:(UIViewController *)fromVC 
      toViewController:(UIViewController *)toVC 
      {
          TransitionAnimator *animator = [TransitionAnimator new]; 
          animator.presenting = YES;
          return animator;
      }
      

      Note that it'll only get called when animated is set to YES. For example

      [navigationController pushViewController:currentViewController animated:YES];
      
    3. Create the animator class extending NSObject. I called mine TransitionAnimator, which was modified from TeehanLax's TLTransitionAnimator inside UIViewController-Transitions-Example.

      TransitionAnimator.h

      #import <Foundation/Foundation.h>
      @interface TransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
      @property (nonatomic, assign, getter = isPresenting) BOOL presenting;
      @end
      

      TransitionAnimator.m

      #import "TransitionAnimator.h"
      @implementation TransitionAnimator
      - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
          return 0.5f;
      }
      - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
          UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
          UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];    
          if (self.presenting) {
              //ANIMATE VC ENTERING FROM THE RIGHT SIDE OF THE SCREEN
              [transitionContext.containerView addSubview:fromVC.view];
              [transitionContext.containerView addSubview:toVC.view];     
              toVC.view.frame = CGRectMake(0, 0, 2*APP_W0, APP_H0); //SET ORIGINAL POSITION toVC OFF TO THE RIGHT                
              [UIView animateWithDuration:[self transitionDuration:transitionContext] 
                  animations:^{
                      fromVC.view.frame = CGRectMake(0, (-1)*APP_W0, APP_W0, APP_H0); //MOVE fromVC OFF TO THE LEFT
                      toVC.view.frame = CGRectMake(0, 0, APP_W0, APP_H0); //ANIMATE toVC IN TO OCCUPY THE SCREEN
                  } completion:^(BOOL finished) {
                      [transitionContext completeTransition:YES];
                  }];
          }else{
              //ANIMATE VC EXITING TO THE RIGHT SIDE OF THE SCREEN
          }
      }
      @end
      

      Use presenting flag to set the direction you want to animate or which ever condition you prefer. Here's the link to Apple reference.

    0 讨论(0)
  • 2020-11-30 22:16

    Simply add in:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    

    This:

    [[self window] setBackgroundColor:[UIColor whiteColor]];
    

    The final result:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {    
        [[self window] setBackgroundColor:[UIColor whiteColor]];
    
        // Override point for customization after application launch.
        return YES;
    }
    
    0 讨论(0)
提交回复
热议问题