还原iOS7以前的UINavigationController pushViewControlleranimation

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

我有一个UINavigationController ,它有子ViewControllers和我使用pushViewController来显示下一个视图。 使用一组图像创build视差animation,如果自定义UINavigationController来为一组UIImageViews设置animation,并且我的子ViewController都有一个self.backgroundColor = [UIColor clearColor] ,透明度。

从iOS7开始, UINavController通过移动当前视图控制器来更新它的子vc的animation,并且在顶部推动新的视图控制器,我的视差animation看起来很糟糕。 我看到以前的VC移动一下,然后消失。 有什么办法可以恢复以前的UINavigationController pushViewControlleranimation? 我似乎无法在代码中find它。

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

有没有人有任何线索?

我设法通过为UINavigationController创build一个类别来解决新的转换types。 在我的情况下,我需要恢复到旧的过渡样式,因为我有透明的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 

我有与清晰的背景颜色和蹩脚的animation相同的问题,所以我创build与新的iOS7 API的ViewController自定义转换。 所有你需要的只是为你的导航控制器设置一个代表:

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

只需将这些文件添加到您的项目: MGNavigationTransitioningDelegate 。

我有一个问题,当UIViewController A做了一个pushViewController来推UIViewController B,推动animation将停止在大约25%,暂停,然后滑动B的余下的方式。

这个DID不会发生在iOS 6上,但是一旦我开始使用iOS 7作为XCode 5中的基础SDK,就开始发生这种情况。

解决方法是视图控制器B没有在其根视图上设置backgroundColor(根视图是viewController.view的值,您通常在loadView中设置)。 在根视图的初始化器中设置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; } 

首先,我没有使用Storyboard。 我尝试使用UINavigationController +复古。 出于某种原因,UINavigationController正在很难释放堆栈顶部的UIViewController。 这里是适用于我使用iOS 7自定义转换的解决scheme。

  1. 将代表设置为自我。

     navigationController.delegate = self; 
  2. 声明这个UINavigationControllerDelegate。

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

    请注意,animation设置为YES时才会被调用。 例如

     [navigationController pushViewController:currentViewController animated:YES]; 
  3. 创build扩展NSObject的animation类。 我叫我的TransitionAnimator,它是从TeehanLax的TLTransitionAnimator在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 

    使用显示标志设置您想要设置animation的方向,或者您喜欢哪种情况。 这里是苹果引用的链接 。

感谢球员的反馈。 find解决scheme,完全重新创buildUINavigationController的行为。 当我几乎完成时,我遇到了Nick Lockwood的解决scheme:

https://github.com/nicklockwood/OSNavigationController

OSNavigationController是UINavigationController的开源重新实现。 它目前只具有UINavigationController的一部分function,但长期目标是复制100%的function。

OSNavigationController实际上并不是按原样使用的。 这个想法是,你可以分叉它,然后轻松地定制其外观和行为,以适应您的应用程序可能有的任何特殊要求。 自定义OSNavigationController比试图自定义UINavigationController简单得多,因为代码是开放的,您不必担心私有方法,无证行为或版本之间的实现更改。

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

谢谢!

只需添加:

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

显然在iOS7中有一种定义自己的自定义UIViewController转换的新方法。 查看UIViewControllerTransitioningDelegate的文档。 另外,这里有一篇关于它的文章链接: http : //www.doubleencore.com/2013/09/ios-7-custom-transitions/

find另一个很好的资源来帮助:

http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions

使用iOS7 TLTransitionAnimator创build自定义animation

我投了@ Arne的答案,因为我觉得这是解决这个问题的最优雅的方法。 我只想添加一些代码,以便从他对@ Arne解决scheme的评论中回答@ Bill的问题。 这是评论报价:

谢谢,这对我有用。 但是,当用户点击“后退”button时,它将恢复到已制作好的animation(因为后退button不会调用popViewControllerRetro)。 – 比尔10月3日12:36

为了在按下后退button时调用popViewControllerRetro,您可以执行一些小操作来实现此目的。 进入你的推视图控制器,导入UIViewController + Retro.h,并添加这个代码在你的viewWillDisappear方法:

 - (void)viewWillDisappear:(BOOL)animated { if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) { [self.navigationController popViewControllerRetro]; } [super viewWillDisappear:animated]; } 

这个if语句将会检测到后退button何时被按下,并且会从category类中调用popViewControllerRetro。

最好的祝福。