Objective c 还原iOS7之前的UINavigationController pushViewController动画

Objective c 还原iOS7之前的UINavigationController pushViewController动画,objective-c,animation,uinavigationcontroller,ios7,pushviewcontroller,Objective C,Animation,Uinavigationcontroller,Ios7,Pushviewcontroller,所以。刚开始将我的IOS代码转换到IOS7,遇到了一些问题 我有一个UINavigationController,它有子视图控制器,我正在使用pushViewController显示下一个视图。若要使用一组图像创建视差动画,请自定义UINavigationController以设置一组UIImageViews的动画,并且我的子视图控制器都具有self.backgroundColor=[UIColor clearColor],透明度 自iOS7以来,UINavController通过部分移动当前视

所以。刚开始将我的IOS代码转换到IOS7,遇到了一些问题

我有一个
UINavigationController
,它有子视图控制器,我正在使用
pushViewController
显示下一个视图。若要使用一组图像创建视差动画,请自定义
UINavigationController
以设置一组
UIImageViews
的动画,并且我的子视图控制器都具有
self.backgroundColor=[UIColor clearColor]
,透明度

自iOS7以来,
UINavController
通过部分移动当前视图控制器并在顶部按下新的viewcontroller来更新其子vc的动画方式,我的视差动画看起来糟透了。我看到以前的VC移动了一点,然后消失了。是否有任何方法可以恢复以前的
UINavigationController
pushViewController动画?我似乎在代码中找不到这个

WelcomeLoginViewController* welcomeLoginViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"WelcomeLogin"];
    [self.navigationController pushViewController:welcomeLoginViewController animated:YES];    
甚至尝试使用:

    [UIView animateWithDuration:0.75
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [self.navigationController pushViewController:welcomeLoginViewController animated:NO];
                         [UIView setAnimationTransition:<specific_animation_form> forView:self.navigationController.view cache:NO];
                     }];
[UIView animateWithDuration:0.75
动画:^{
[UIView设置动画曲线:UIViewAnimationCurveEaseInOut];
[self.navigationController pushview控制器:welcomeLoginViewController动画:否];
[UIView setAnimationTransition:forView:self.navigationController.view缓存:否];
}];

有人有任何线索吗?

我通过为
UINavigationController
创建一个类别,设法绕过了新的转换类型。在我的例子中,我需要将其恢复为旧的过渡样式,因为我有透明的ViewController,可以在静态背景上滑动

  • UINavigationController+Retro.h

    @interface UINavigationController (Retro)
    
    - (void)pushViewControllerRetro:(UIViewController *)viewController;
    - (void)popViewControllerRetro;
    
    @end
    
  • UINavigationController+Retro.m

    #import "UINavigationController+Retro.h"
    
    @implementation UINavigationController (Retro)
    
    - (void)pushViewControllerRetro:(UIViewController *)viewController {
        CATransition *transition = [CATransition animation];
        transition.duration = 0.25;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFromRight;
        [self.view.layer addAnimation:transition forKey:nil];
    
        [self pushViewController:viewController animated:NO];
    }
    
    - (void)popViewControllerRetro {
        CATransition *transition = [CATransition animation];
        transition.duration = 0.25;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFromLeft;
        [self.view.layer addAnimation:transition forKey:nil];
    
        [self popViewControllerAnimated:NO];
    }
    
    @end
    

    • 感谢各位的反馈。找到了完全重新创建UINavigationController行为的解决方案。当我快做完的时候,我遇到了尼克·洛克伍德的解决方案:

      OSNavigationController是UINavigationController的开源重新实现。它目前只具有UINavigationController功能的一个子集,但长期目标是复制100%的功能

      OSNavigationController实际上并不打算按原样使用。这样做的目的是,您可以将其分叉,然后轻松定制其外观和行为,以满足您的应用程序可能具有的任何特殊要求。自定义OSNavigationController比尝试自定义UINavigationController简单得多,因为代码是开放的,您不需要担心私有方法、未记录的行为或版本之间的实现更改

      通过用他的代码覆盖我的UINavigationController,我能够在UINavigationcontrollers中处理背景图像


      谢谢

      显然,在iOS7中,有一种新的方式定义您自己的自定义UIViewController转换。在文档中查找UIViewControllerTransitioningDelegate。另外,这里还有一个关于它的文章链接:

      找到了另一个很好的帮助资源:


      使用iOS7 TLTransitionAnimator创建自定义动画时,我遇到了一个问题,当UIViewController a使用pushViewController来推UIViewController B时,推送动画将在25%左右停止,然后在剩余的过程中滑动B

      这在iOS 6上没有发生,但当我开始在XCode 5中使用iOS 7作为基本SDK时,这种情况就开始发生了

      修复方法是视图控制器B在其根视图上没有设置backgroundColor(根视图是通常在loadView中设置的viewController.view的值)。在根视图的初始值设定项中设置backgroundColor修复了该问题

      我成功地解决了这个问题,如下所示:

      // CASE 1: The root view for a UIViewController subclass that had a halting animation
      
      - (id)initWithFrame:(CGRect)frame
      
      {
      
           if ((self = [super initWithFrame:frame])) {
      
                // Do some initialization ...
      
                // self.backgroundColor was NOT being set
      
                // and animation in pushViewController was slow and stopped at 25% and paused
      
           }
      
           return self;
      
      }
      
      // CASE 2: HERE IS THE FIX
      
      - (id)initWithFrame:(CGRect)frame
      
      {
      
           if ((self = [super initWithFrame:frame])) {
      
                // Do some initialization ...
      
                // Set self.backgroundColor for the fix!
      
                // and animation in pushViewController is no longer slow and and no longer stopped at 25% and paused
      
                self.backgroundColor = [UIColor whiteColor]; // or some other non-clear color
      
           }
      
           return self;
      
      }
      

      首先,我不使用故事板。我尝试使用UINavigationController+Retro。出于某种原因,UINavigationController很难在堆栈顶部释放UIViewController。以下是使用iOS 7自定义转换为我提供的解决方案

    • 将委托设置为self

      navigationController.delegate = self;
      
    • 声明此UINavigationControllerDelegate

      - (id<UIViewControllerAnimatedTransitioning>)navigationController (UINavigationController *)navigationController 
      animationControllerForOperation:(UINavigationControllerOperation)operation
      fromViewController:(UIViewController *)fromVC 
      toViewController:(UIViewController *)toVC 
      {
          TransitionAnimator *animator = [TransitionAnimator new]; 
          animator.presenting = YES;
          return animator;
      }
      
    • 创建扩展NSObject的animator类。我叫我的TransitionAnimator,它是从TeehanLax的TLTransitionAnimator内部修改而来的

      过渡反应器

      #import <Foundation/Foundation.h>
      @interface TransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
      @property (nonatomic, assign, getter = isPresenting) BOOL presenting;
      @end
      
      #导入
      @接口TransitionAnimator:NSObject
      @属性(非原子、赋值、getter=isPresenting)布尔呈现;
      @结束
      
      传递函数

      #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
      
      #导入“TransitionAnimator.h”
      @实现传递器
      -(NSTimeInterval)transitionDuration:(id)transitionContext{
      返回0.5f;
      }
      -(void)animateTransfion:(id)transitionContext{
      UIViewController*fromVC=[transitionContext ViewControllerWorky:UITransitionContextFromViewControllerKey];
      UIViewController*toVC=[transitionContext ViewControllerWorky:UITransitionContextToViewControllerKey];
      如果(自我介绍){
      //设置VC从屏幕右侧进入的动画
      [transitionContext.containerView添加子视图:fromVC.view];
      [transitionContext.containerView添加子视图:toVC.view];
      toVC.view.frame=CGRectMake(0,0,2*APP_W0,APP_H0);//将原始位置设置为右侧的VC OFF
      [UIView animateWithDuration:[自转换持续时间:转换上下文]
      动画:^{
      fromVC.view.frame=CGRectMake(0,(-1)*APP_W0,APP_W0,APP_H0);//将fromVC移到左侧
      toVC.view.frame=CGRectMake(0,0,APP_W0,APP_H0);//设置toVC的动画以占据屏幕
      }完成:^(布尔完成){
      [transitionContext completeTransition:是];
      }];
      }否则{
      //设置VC退出到屏幕右侧的动画
      }
      }
      @结束
      
      使用presenting flag可设置要设置动画的方向或您喜欢的条件
      #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
      
      - (void)viewWillDisappear:(BOOL)animated {
          if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
              [self.navigationController popViewControllerRetro];
          }
      
          [super viewWillDisappear:animated];
      }
      
      // NavigationController does not retain delegate, so you should hold it.
      self.navigationController.delegate = self.navigationTransitioningDelegate;
      
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      
      [[self window] setBackgroundColor:[UIColor whiteColor]];
      
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {    
          [[self window] setBackgroundColor:[UIColor whiteColor]];
      
          // Override point for customization after application launch.
          return YES;
      }