Comment créer des transitions et des animations de contrôleur de vue personnalisées

introduction

UIKit est un framework très puissant et fournit différentes manières de faire la transition entre les contrôleurs de vue. Certaines des animations fournies par UIKit incluent le glissement horizontal (via une séquence push), le glissement vertical, le fondu enchaîné et le retournement de page. Cependant, il est parfois nécessaire de prévoir une transition personnalisée entre les contrôleurs de vue pour créer une conception attrayante ou offrir une expérience utilisateur unique. Photos de Apple pour iOS lors de la sélection d'une photo est un bon exemple de transition personnalisée..

Dans ce tutoriel, je vous explique comment créer vos propres transitions personnalisées à l'aide de plusieurs API UIKit..

Exigences

Alors que les API utilisées pour créer des transitions personnalisées ont été introduites dans iOS 7, ce didacticiel utilise Auto Layout et Swift 2, ce qui signifie que vous devez exécuter Xcode 7+ sur OS X Yosemite ou une version ultérieure. Vous devez également télécharger le projet de démarrage depuis GitHub..

1. Composants d'une transition personnalisée

Lorsque vous implémentez une transition de contrôleur de vue personnalisée, vous devez prendre en compte deux composants principaux:

  • contrôleur d'animation, également appelé le animateur
  • délégué en transition, un contrôleur de vue que vous affectez

le animateur object est responsable de la transition en termes de durée et de logique d’animation des vues. Le contrôleur d’animation de votre application peut être n’importe quel type d’objet, à condition qu’il soit conforme à la UIViewControllerAnimatedTransitioning protocole.

le délégué en transition est chargé de fournir le contrôleur d'animation à utiliser pour la transition personnalisée. L’objet délégué que vous désignez doit être conforme à la UIViewControllerTransitioningDelegate protocole.

2. Créer une transition personnalisée

Ouvrez le projet de démarrage et exécutez votre application. Lorsque vous appuyez sur le Appuyez sur pour voir bouton, la transition modale verticale standard est actuellement utilisée.

Créez un nouveau fichier en sélectionnant Nouveau> Fichier… du Fichier menu. Parmi les options affichées, sélectionnez iOS> Source> Swift Fichier et nommer le fichier CustomTransition. Ce fichier va contenir la logique nécessaire à la transition personnalisée.

Tout d'abord, nous allons définir la classe du contrôleur d'animation qui sera utilisée pour la transition personnalisée. Ajoutez le code suivant à CustomTransition.swift:

import UIKit enum TransitionType case Présentant, Rejetant classe AnimationController: NSObject, UIViewControllerAnimatedTransitioning durée: NDSimeInterval: Format, format, format, format, format, format, format, format, format, format. durée self.isPresenting = type == .Présentation de self.originFrame = originFrame super.init () func transitionDuration (transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval return self.duration

Nous définissons un Type de transition énumération, qui est utilisée lors de la création d'un AnimationContrôleur objet.

Ensuite, nous définissons le AnimationContrôleur classe avec quelques propriétés. le durée propriété va être utilisée pour déterminer la durée de l'animation et est la valeur retournée dans le UIViewControllerAnimatedTransitioning méthode du protocole transitionDurée (_ :). Cette durée ne doit pas nécessairement être une variable, mais il est plus facile de la modifier si elle n'est définie qu'une seule fois lors de la création du contrôleur d'animation. Les deux estprésentant et origineFrame les propriétés seront utilisées pour créer l'animation de la transition.

À ce stade, Xcode devrait vous présenter une erreur. C’est parce que nous n’avons pas implémenté la méthode requise du UIViewControllerAnimatedTransitioning protocole. Avant de mettre en œuvre cette méthode, il y a une chose importante que vous devez savoir.

Lorsque votre transition personnalisée commence, UIKit vous fournit une vue de conteneur dans laquelle vous devez exécuter les animations pour la transition. Dans cette vue conteneur, vous devez ajouter manuellement la vue du contrôleur de vue vers lequel vous effectuez la transition. Cette vue conteneur ne vit que pendant la durée de la transition et est supprimée de la hiérarchie des vues dès que votre animation est terminée..

Nous allons maintenant implémenter l'animation personnalisée. Ajoutez la méthode suivante à la AnimationContrôleur classe:

func animateTransition (transitionContext: UIViewControllerContextTransitioning) let conteneurView = transitionContext.containerView ()! let fromView = transitionContext.viewControllerForKey (UITransitionContextFromViewControllerKey)!. view let toView = transitionContext.viewControllerForKey (UITransitionContextToViewControllerKey)!! let let detailView = self.isPresenting? toView: fromView si self.isPresenting containerView.addSubview (toView) else containerView.insertSubview (toView, belowSubview: fromView) detailView.frame.origin = self.isPresenting? self.originFrame.origin: CGPoint (x: 0, y: 0) detailView.frame.size.width = self.isPresenting? self.originFrame.size.width: containerView.bounds.width detailView.layoutIfNeeded () pour afficher en détailView.subviews if! (la vue est UIImageView) view.alpha = isPresenting? 0.0: 1.0 UIView.animateWithDuration (self.duration, animations: () -> Nul dans detailView.frame = self.isPresenting? ContainerView.bounds: self.originFrame detailView.layoutIfNeeded () pour afficher en détailView.subviews if ! (view est UIImageView) view.alpha = self.isPresenting? 1.0: 0.0 terminé: Bool) -> Nul dans transitionContext.completeTransition (! transitionContext.transitionWasCancelled ())

Nous commençons cette méthode en récupérant la vue conteneur du contexte de transition fourni en utilisant le containerView () méthode. Nous accédons au de et à vues en invoquant le viewControllerForKey (_ :) méthode, passage UITransitionContextFromViewControllerKey et UITransitionContextToViewControllerKey respectivement.

Dans iOS 8 et versions ultérieures, vous pouvez accéder directement aux vues à l'aide de la viewForKey (_ :) méthode et la UITransitionContextFromViewKey et UITransitionContextToViewKey clés.

Dans le corps de la méthode, nous animons la vue de détail afin de l’agrandir ou de la réduire en utilisant UIView API d'animation.

La dernière chose importante à noter est la completeTransition (_ :) méthode appelée sur l'objet de contexte de transition. Cette méthode doit être appelée une fois que votre animation est terminée pour que le système sache que vos contrôleurs de vue ont terminé la transition. Cette méthode accepte un booléen en tant que paramètre unique, qui indique si la transition est terminée ou non..

Avec cette implémentation, nous avons créé un contrôleur d’animation entièrement fonctionnel. Pour réellement mettre en œuvre cela, nous devons maintenant mettre en place un délégué de transition.

3. Affecter un délégué en transition

Comme je l'ai mentionné plus tôt, le travail du délégué en transition est de fournir l'objet contrôleur d'animation pour une transition entre deux contrôleurs de vue. Le délégué de transition peut être l’objet de votre choix, mais la pratique courante consiste à définir le contrôleur comme contrôleur de présentation..

Dans CustomTransition.swift, ajoutez le code suivant sous le AnimationContrôleur définition de classe:

extension de ViewController: UIViewControllerTransitioningDelate return AnimationController (withDuration: 3.0, forTransitionType: .Mettre a distance, originFrame: self.image.frame) func animationControllerForPresentedController (présenté: UIViewController, presentationController présentant: UIViewController, sourceController) return AnimationController (withDurée: 3.0, forTransitionType: .Presenting, originFrame: self.image.frame)

En mettant en œuvre cette extension, nous faisons la ViewController classe conforme à la UIViewControllerTransitioningDelegate protocole et mettre en œuvre trois méthodes. La première, prepareForSegue (_: expéditeur :), est utilisé pour désigner le courant ViewController instance comme destination DetailViewController objets transitiondelegate. Les deux autres méthodes créent un AnimationContrôleur objet de présentation et de suppression du contrôleur de vue à l'aide de l'initialiseur défini précédemment. Si tu reviens néant à partir de l’une de ces méthodes, la transition du contrôleur de vue standard ou par défaut sera utilisée à la place.

Avec la configuration du délégué de transition, il est temps de créer et d'exécuter votre application. Cette fois où vous appuyez sur le Appuyez sur pour voir bouton, vous devriez voir l’icône Xcode grossir et que les autres étiquettes s’affichent en fondu. De même, lorsque vous appuyez sur la touche Appuyez sur pour fermer bouton, vous devriez voir la même animation mais en sens inverse.

Toutes nos félicitations. Vous avez maintenant créé avec succès votre toute première transition de contrôleur de vue personnalisée sur iOS..

4. Faire une transition interactive

Pour rendre la transition personnalisée encore meilleure, nous allons la rendre interactive et réactive. Un bon exemple de ceci est le UINavigationController glisser le geste du bord gauche pour revenir en arrière.

Pour rendre une transition personnalisée interactive, vous devez d’abord avoir un objet conforme à la UIViewControllerInteractiveTransitioning protocole. Pour ce tutoriel, nous allons utiliser une classe fournie par UIKit qui est déjà conforme à ce protocole., UIPercentDrivenInteractiveTransition.

Afin de pouvoir communiquer facilement entre les contrôleurs de vue (le délégué en transition et le contrôleur de vue déterminant le pourcentage d'achèvement de la transition), ouvrez DetailViewController.swift et ajoutez la propriété suivante à la DetailViewController classe:

var rootViewController: ViewController!

Ensuite, ajoutez le code suivant à la didPanDown (_ :) méthode du DetailViewController classe:

@IBAction func didPanDown (expéditeur: UIPanGestureRecognizer) let progress = sender.translationInView (self.view) .y / self.view.frame.size.height switch sender.state case .Began: self.rootViewController.interactionController.interactionController.Utiliser ) self.dismissViewControllerAnimated (true, complétion: nil) cas .Changed: self.rootViewController.interactionController? .updateInteractiveTransition (progrès) cas .Ended: if progrès> = 0.5 self.rootViewController.interactionController.interactionController? .finish) .rootViewController.interactionController? .cancelInteractiveTransition () self.rootViewController.interactionController = nil défaut: self.rootViewController.interactionController? .cancelInteractiveTransition () self.rootViewController.interactionController = nal

dans le didPanDown (_ :) méthode, nous calculons la valeur de la le progrès variable en fonction de la distance parcourue par l'utilisateur par rapport à la vue détaillée. Si le panoramique vient de commencer, nous créons l'objet contrôleur d'interaction et commençons le renvoi du contrôleur de vue. Chaque fois que le mouvement de panoramique se déplace dans la vue, nous mettons à jour le contrôleur d'interaction en indiquant le degré d'avancement de la transition..

Enfin, lorsque le panoramique est terminé, nous finissons ou annulons la transition en utilisant le bouton finishInteractiveTransition () et cancelInteractiveTransition () méthodes respectivement.

Ensuite, retournez à CustomTransition.swift et remplacer le prepareForSegue (_: expéditeur :) méthode dans le ViewController extension de classe avec les éléments suivants:

remplacez func prepareForSegue (segue: UIStoryboardSegue, expéditeur: AnyObject?) segue.destinationViewController.transitioningDelegate = self (segue.destinationViewController comme? DetailViewController)??

Dans prepareForSegue (_: expéditeur :), nous donnons au contrôleur de vue de détail un accès au contrôleur de vue racine.

Enfin, ajoutez la méthode suivante à la ViewController extension:

func interactionControllerForDismissal (animateur: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? return self.interactionController

le interactionControllerForDismissal (_ :) méthode retourne le contrôleur de vue racine interactionController. Si c'est néant (par exemple, si le bouton est exploité), l'animation personnalisée sera utilisée à la place.

Comme on peut s’y attendre, un contrôleur interactif peut également être utilisé lors de la présentation de contrôleurs de vue en implémentant la interactionControllerForPresentation (_ :) méthode.

Générez et exécutez votre application une dernière fois et, après avoir présenté votre contrôleur de vue de détail, faites glisser l'écran vers le bas et vous verrez la transition bouger en phase avec la position de votre doigt..

Conclusion

Vous devriez maintenant être à l'aise pour créer des transitions de contrôleur de vue personnalisées entièrement interactives sur iOS. Comme vous pouvez le constater, ces API ne sont retenues que par les fonctionnalités d’animation de UIKit et Core Animation. Ils peuvent être utilisés pour presque n'importe quel type de transition. Comme toujours, laissez vos commentaires dans les commentaires ci-dessous.