Sobes.tech
Junior — Middle

Comment peut-on réaliser une transition animée personnalisée lors du passage entre les écrans dans un Navigation Controller?

sobes.tech IA

Réponse de l'IA

Pour implémenter une transition animée personnalisée entre les écrans dans UINavigationController, vous devez utiliser les protocoles UIViewControllerAnimatedTransitioning et UINavigationControllerDelegate.

  1. Créez une classe qui implémente UIViewControllerAnimatedTransitioning, où vous décrivez la logique de l'animation dans les méthodes:

    • transitionDuration(using:) — durée de l'animation
    • animateTransition(using:) — l'animation elle-même
  2. Définissez comme délégué du UINavigationController un objet qui implémente UINavigationControllerDelegate, et dans la méthode:

    func navigationController(_ navigationController: UINavigationController, 
                              animationControllerFor operation: UINavigationController.Operation, 
                              from fromVC: UIViewController, 
                              to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        // renvoie votre objet d'animation
        return customAnimator
    }
    

Exemple d'un animateur personnalisé simple:

class CustomAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let toView = transitionContext.view(forKey: .to) else {
            transitionContext.completeTransition(false)
            return
        }
        let container = transitionContext.containerView
        toView.alpha = 0
        container.addSubview(toView)

        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toView.alpha = 1
        }) { finished in
            transitionContext.completeTransition(finished)
        }
    }
}