恢复iOS7之前的UINavigationController pushViewController动画

Bar*_*erg 38 animation objective-c uinavigationcontroller pushviewcontroller ios7

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

我有一个UINavigationController,它有子ViewControllers,我pushViewController用来显示下一个视图.要创建带有一组图像的视差动画,如果自定义UINavigationController动画一组UIImageViews和我的孩子ViewControllers都具有self.backgroundColor = [UIColor clearColor]透明度.

由于iOS7,UINavController动画它的子vc的方式,通过部分移动当前视图控制器更新,并在顶部推动新的视图控制器,我的视差动画看起来很废话.我看到之前的VC移动了一点然后消失了.有什么办法可以恢复以前的UINavigationControllerpushViewController动画吗?我似乎无法在代码中找到它.

WelcomeLoginViewController* welcomeLoginViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"WelcomeLogin"];
    [self.navigationController pushViewController:welcomeLoginViewController animated:YES];    
Run Code Online (Sandbox Code Playgroud)

甚至尝试使用:

    [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];
                     }];
Run Code Online (Sandbox Code Playgroud)

有没有人有任何线索?

Arn*_*rne 46

我设法通过创建一个类别来解决新的转换类型UINavigationController.在我的情况下,我需要将其恢复为旧的过渡样式,因为我有透明的viewControllers在静态背景上滑动.

  • UINavigationController的+ Retro.h

    @interface UINavigationController (Retro)
    
    - (void)pushViewControllerRetro:(UIViewController *)viewController;
    - (void)popViewControllerRetro;
    
    @end
    
    Run Code Online (Sandbox Code Playgroud)
  • 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
    
    Run Code Online (Sandbox Code Playgroud)


Art*_*eel 22

我有明确的背景颜色和蹩脚的动画相同的问题,所以我使用新的iOS7 API为ViewController创建自定义过渡.您只需为导航控制器设置一个代理:

// NavigationController does not retain delegate, so you should hold it.
self.navigationController.delegate = self.navigationTransitioningDelegate;
Run Code Online (Sandbox Code Playgroud)

只需将此文件添加到您的项目中:MGNavigationTransitioningDelegate.

  • 出色的工作,这解决了我的问题. (3认同)

Joe*_*oel 18

我有一个问题,当UIViewController A执行pushViewController推UIViewController B时,推动画将停止在25%左右,停止,然后在剩下的路上滑动B.

这个DID不会发生在iOS 6上,但是当我开始在XCode 5中使用iOS 7作为基础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;

}
Run Code Online (Sandbox Code Playgroud)


小智 7

首先,我没有使用Storyboard.我尝试使用UINavigationController + Retro.由于某种原因,UINavigationController很难在堆栈顶部释放UIViewController.这是适用于iOS 7自定义转换的解决方案.

  1. 将代表设置为自己.

    navigationController.delegate = self;
    
    Run Code Online (Sandbox Code Playgroud)
  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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,只有在动画设置为YES时才会调用它.例如

    [navigationController pushViewController:currentViewController animated:YES];
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建扩展NSObject的动画类.我打电话给我的TransitionAnimator,它是在UIViewController-Transitions-Example中从TeehanLax的TLTransitionAnimator修改的.

    TransitionAnimator.h

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

    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
    
    Run Code Online (Sandbox Code Playgroud)

    使用呈现标志设置您想要设置动画的方向或您喜欢的条件.这是Apple参考的链接.


Bar*_*erg 2

谢谢大家的反馈。找到了完全重新创建 UINavigationController 行为的解决方案。当我快要完成时,我遇到了尼克·洛克伍德的解决方案:

https://github.com/nicklockwood/OSNavigationController

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

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

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

谢谢!