Как переходить на разрастание при нажатии просмотров на UINavigationController в iOS 7?

Если я просто вызываю метод push с помощью:

[self.navigationController pushViewController:viewController animated:YES];

то он использует анимацию push. Как мне изменить его, чтобы использовать анимацию с крестом, как я могу, с модальным отступлением?

Ответ 1

Вы можете использовать CATransition, как показано в этом ответе:

CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.type = kCATransitionFade;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[self.navigationController pushViewController:viewController animated:NO];

Ответ 2

Я использую расширение для легкого повторного использования:

extension UINavigationController {
    func fadeTo(_ viewController: UIViewController) {
        let transition: CATransition = CATransition()
        transition.duration = 0.3
        transition.type = kCATransitionFade
        view.layer.add(transition, forKey: nil)
        pushViewController(viewController, animated: false)
    }
}

Обратите внимание, что анимация ложна; когда вы устанавливаете его в true, вы все равно видите стандартную анимацию "push" (справа налево).

Ответ 3

Протокол UINavigationControllerDelegate имеет метод, который может возвращать пользовательский объект UIViewControllerAnimatedTransitioning, который будет управлять анимацией между двумя контроллерами представления, участвующими в переходе.

Создайте класс Animator для управления переходом перекрестного растворения:

class Animator: NSObject, UIViewControllerAnimatedTransitioning {

    let animationDuration = 0.25

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return animationDuration
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
        toVC?.view.alpha = 0.0
        let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
        transitionContext.containerView.addSubview(fromVC!.view)
        transitionContext.containerView.addSubview(toVC!.view)

        UIView.animate(withDuration: animationDuration, animations: {
            toVC?.view.alpha = 1.0
        }) { (completed) in
            fromVC?.view.removeFromSuperview()
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
}

И предоставьте это в своем UINavigationControllerDelegate:

func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return Animator()
}

Вот более подробное руководство: http://blog.rinatkhanov.me/ios/transitions.html

Ответ 4

SWIFT 3, 4.2 - по состоянию на октябрь 2019 года

let transition = CATransition()
transition.duration = 0.5
transition.type = kCATransitionFade
self.navigationController?.view.layer.add(transition, forKey:nil)

Ответ 5

Вы можете установить Push viewcontroller следующим образом.

        CATransition* transition = [CATransition animation];
        transition.duration = 0.4;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        transition.type = kCATransitionFade;
        [self.navigationController.view.layer addAnimation:transition forKey:@"kCATransition"];
        [self.navigationController pushViewController:readerViewController animated:false];

Вы можете установить Pop viewcontroller следующим образом.

         CATransition* transition = [CATransition animation];
         transition.duration = 0.4;
         transition.timingFunction = [CAMediaTimingFunction 
         functionWithName:kCAMediaTimingFunctionEaseOut];
         transition.type = kCATransitionFade;
         [self.navigationController.view.layer addAnimation:transition 
          forKey:@"kCATransition"];
         [self.navigationController popViewControllerAnimated:false];

Ответ 6

Обновление Swift 5

Использование prepare(for segue:) вместо pushViewController:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // other preparations

    let transition: CATransition = CATransition()
    transition.duration = 0.3
    transition.type = CATransitionType.fade
    navigationController?.view.layer.add(transition, forKey: nil)
}