iOS 7改变了pushviewcontroller的动画方向

use*_*901 6 animation push direction ios

当我推动一个视图控制器时,动画总是从右到左.我想将该动画从左向右反转.我尝试过这段代码但不起作用.动画仍然是从右到左.我怎样才能简单而正确地实现这一目标?需要帮助.提前致谢.

//NOT WORKING
myViewController *mController = [self.storyboard instantiateViewControllerWithIdentifier:@"myViewController"];

CATransition *transition = [CATransition animation];
transition.duration = 0.3;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;

[self.view.layer addAnimation:transition forKey:nil];

[self.navigationController pushViewController:mController animated:YES];
Run Code Online (Sandbox Code Playgroud)

Dan*_*sko 11

由于这个问题提到了iOS 7,我很惊讶答案没有提到iOS 7中引入的Animated Transitions API.

如果你想直接进入GitHub,objc.io的人在这里有一个很棒的帖子和链接项目

看一下文档,您将看到以下内容:

@availability(iOS, introduced=7.0)
optional func navigationController(navigationController: UINavigationController, 
animationControllerForOperation operation: UINavigationControllerOperation, 
fromViewController fromVC: UIViewController,
 toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
Run Code Online (Sandbox Code Playgroud)

或者在Objective-C中

- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);
Run Code Online (Sandbox Code Playgroud)

这意味着从iOS 7开始,您可以控制导航控制器如何实现推送和弹出的动画.

所需的只是您设置导航控制器的委托并在适当时提供正确的动画制作对象.让我们开始吧:

1.设置UINavigationControllerDelegate

我通常喜欢使用应用程序范围的导航协调器来管理我的所有转换等.理想情况下,您需要一些在NavigationController持续时间内处于活动状态的对象.所以我们可能会有一个看起来像这样的协调器:

class NavigationCoordinationController: NSObject {
    private(set) var navigationController:UINavigationController        

    required init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        super.init()
        navigationController.delegate = self
    }
}
Run Code Online (Sandbox Code Playgroud)

我通常在App Delegate中创建它,以便可以在任何地方引用它.您还可以基于每个视图控制器设置委托,创建自定义UINavigationController子类,或者您认为合适的位置.

2.创建自定义动画师

现在我们需要一个符合UIViewControllerAnimatedTransitioning协议的对象.每当需要动画转换时,将调用此对象来应用动画.此示例是一个简单的动画,它在转换中淡化和扩展fromView,因此它与Push相关.

class CustomPushExpansionTransitioner: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
        return 1
    }

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let fromView: UIView = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
        let toView: UIView = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
        let container = transitionContext.containerView()
        container.addSubview(toView)
        container.bringSubviewToFront(fromView)

        toView.frame = container.convertRect(fromView.bounds, fromView: fromView)

        UIView.animateWithDuration(transitionDuration(transitionContext),
            animations: { () -> Void in
                fromView.alpha = 0
                fromView.transform = CGAffineTransformConcat(fromView.transform, CGAffineTransformMakeScale(1.3, 1.3))
        }) { (complete) -> Void in
            transitionContext.completeTransition(true)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

3.供应动画师必要的地方

现在我们需要实现UINavigationController委托并在需要时出售我们的自定义动画师.

extension NavigationCoordinationController: UINavigationControllerDelegate {
    func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        switch operation {
        case .Push:
            return LaunchToHomeTransitioner()
        case .Pop:
            break
        case .None:
            break
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

你去了,你现在可以完全控制你的UINavigationController过渡


gra*_*n33 9

您实际上是正确的,但据我所知,从您的代码中,您没有覆盖该方法:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
Run Code Online (Sandbox Code Playgroud)

因此,您需要继承UINavigationController并覆盖上述方法.

这是我的方式(推+弹出):

推:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    UIView *theWindow = self.view ;
    if( animated ) {
        CATransition *animation = [CATransition animation];
        [animation setDuration:0.45f];
        [animation setType:kCATransitionPush];
        [animation setSubtype:kCATransitionFromLeft];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
        [[theWindow layer] addAnimation:animation forKey:@""];
    }

    //make sure we pass the super "animated:NO" or we will get both our
    //animation and the super's animation
    [super pushViewController:viewController animated:NO];

    [self swapButtonsForViewController:viewController];

}
Run Code Online (Sandbox Code Playgroud)

流行:

- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
    UIView *theWindow = self.view ;
    if( animated ) {
        CATransition *animation = [CATransition animation];
        [animation setDuration:0.45f];
        [animation setType:kCATransitionPush];
        [animation setSubtype:kCATransitionFromRight];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
        [[theWindow layer] addAnimation:animation forKey:@""];
    }
    return [super popViewControllerAnimated:NO];
}
Run Code Online (Sandbox Code Playgroud)