Fermer

novembre 20, 2019

Exécution d'animations iOS sur des vues avec UIKit et UIView


Cet article se veut une introduction aux animations iOS couvrant de manière exhaustive différentes manières de le faire. Nous commençons par comprendre les bases des animations, puis nous passons à Core Frameworks en construisant un seul exemple à l'aide des différentes méthodes proposées, puis en recherchant des moyens d'optimiser les performances.

Je suis développeur iOS depuis plus de 10 ans et je n'ai que rarement articles vus qui regroupent tous les moyens possibles pour réaliser des animations dans iOS. Cet article se veut une introduction aux animations iOS dans le but de couvrir de manière exhaustive les différentes façons de faire la même chose.

Compte tenu de l'ampleur du sujet, nous aborderons chaque partie de manière succincte à un niveau assez élevé. L'objectif est d'éduquer le lecteur avec un ensemble de choix pour ajouter des animations à son application iOS.

Avant de commencer avec des sujets liés à iOS, jetons un bref aperçu de la vitesse d'animation.

60FPS

Généralement, dans les vidéos, chaque image est représentée par une image et la cadence détermine le nombre d'images retournées dans la séquence. Il s’agit de «images par seconde» ou FPS.

FPS détermine le nombre d’images fixes retournées en une seconde, ce qui signifie littéralement que plus le nombre d’images / images est important, plus la vidéo affiche de détails / d’informations. Cela est également vrai pour les animations.

Le FPS est généralement utilisé pour déterminer la qualité des animations. Il est généralement admis que toute bonne animation doit être exécutée à 60 images par seconde ou plus – tout ce qui est inférieur à 60 images par seconde serait un peu gênant.

Voulez-vous voir la différence entre 30 images par seconde et 60 images par seconde? Vérifiez ceci !

Avez-vous remarqué la différence? Les yeux humains peuvent certainement ressentir la gigue à des degrés inférieurs. Par conséquent, il est toujours recommandé de s'assurer que toute animation que vous créez respecte la règle de base de l'exécution à 60 images par seconde ou plus. Cela le rend plus réaliste et plus vivant.

Après avoir examiné FPS, examinons maintenant les différents frameworks centraux iOS qui nous permettent d'effectuer des animations.

Core Frameworks

Dans cette section, nous allons aborder sur les frameworks du SDK iOS qui peuvent être utilisés pour créer des animations de vue. Nous allons parcourir rapidement chacun d'eux, en expliquant leurs fonctionnalités à l'aide d'un exemple pertinent.

UIKit / UIView Animations

UIView est la classe de base de toute vue affichant du contenu dans des applications iOS.

Le framework qui nous donne UIView fournit déjà quelques fonctions d’animation de base qui permettent aux développeurs d’obtenir plus en faisant moins.

L’API, UIView.animate est le moyen le plus simple d’animer des vues. étant donné que toutes les propriétés d'une vue peuvent être facilement animées en fournissant les valeurs de propriété dans la syntaxe basée sur les blocs.

Dans les animations UIKit, il est recommandé de modifier uniquement les propriétés pouvant être animées de UIVIew, sans quoi les animations pourraient provoquer l'affichage. pour se retrouver dans un état inattendu.

animation (withDuration: animations: complétion)

Cette méthode prend en compte la durée de l'animation, un ensemble de modifications de propriétés animables de la vue qui doivent être animées. Le bloc d'achèvement donne un rappel lorsque la vue est terminée lors de l'exécution de l'animation.

Presque tous les types d'animation tels que le déplacement, la mise à l'échelle, la rotation, le fondu, etc. d'une vue peuvent être atteints avec cette API unique.

Maintenant , considérez que vous souhaitez animer un changement de taille de bouton ou que vous souhaitez qu’un affichage particulier fasse un zoom sur l’écran. Voici comment procéder à l'aide de l'API UIView.animate :

 let newButtonWidth: CGFloat = 60

UIView.animate (withDurée: 2.0) {// 1
    self.button.frame = CGRect (x: 0, y: 0, largeur: newButtonWidth, hauteur: newButtonWidth) // 2
    self.button.center = self.view.center // 3
} 

Voici ce que nous faisons ici:

  1. Nous appelons la méthode UIView.animate avec une valeur de durée qui lui est transmise et qui indique la durée de l'animation décrite dans le bloc. 19659026] Nous définissons le nouveau cadre du bouton qui devrait représenter l'état final de l'animation.
  2. Nous définissons le bouton au centre avec le centre de sa vue principale de sorte qu'il reste au centre de l'écran. 19659028] Le bloc de code d'animation ci-dessus doit déclencher l'animation de l'image du bouton, qui est modifiée à partir de l'image actuelle:

    Width = 0, Height = 0

    Jusqu'à l'image finale:

    Width = Height = newButtonWidth

    Et voici à quoi ressemblerait l'animation:

    animateWithDuration: delay: usingSpringWithDamping: initialSpringVelocity: options: animations: complétion

    Cette méthode est comme une extension de la méthode animate permettant d'effectuer tout ce que vous pouvez effectuer auparavant. API avec physique beha viors ajouté aux animations de vue.

    Par exemple, si vous souhaitez obtenir des effets d'amortissement du ressort dans l'animation que nous avons effectuée ci-dessus, le code ressemblerait à ceci:

     laissez newButtonWidth: CGFloat = 60
    UIView.animate (withDurée: 1.0, // 1
        délai: 0.0, // 2
        usingSpringWithDamping: 0.3, // 3
        initialSpringVelocity: 1, // 4
        options: UIView.AnimationOptions.curveEaseInOut, // 5
        animations: ({// 6
            self.button.frame = CGRect (x: 0, y: 0, largeur: newButtonWidth, hauteur: newButtonWidth)
            self.button.center = self.view.center
    }), complétion: nil) 

    Voici l'ensemble des paramètres que nous utilisons:

    1. duration
      Représente la durée de l'animation déterminant la durée d'exécution du bloc de code.
    2. delay
      Représente le délai initial que nous souhaitons avoir avant le début de l'animation.
    3. SpringWithDamping
      Représente la valeur de l'effet d'élasticité que nous souhaitons que la vue se comporte. La valeur doit être comprise entre 0 et 1. Plus la valeur est basse, plus l'oscillation du ressort est élevée.
    4. vélocité
      Représente la vitesse à laquelle l'animation doit commencer.
    5. options
      Type de courbe d'animation que vous souhaitez appliquer à votre animation de vue.
    6. Enfin, le bloc de code dans lequel nous définissons l'image du bouton à animer. C'est la même chose que l'animation précédente.

    Et voici à quoi ressemblerait l'animation avec la configuration d'animation ci-dessus:

    UIViewPropertyAnimator

    Pour un peu plus de contrôle sur les animations, UIViewPropertyAnimator est pratique. où il nous fournit un moyen de mettre en pause et de reprendre les animations. Vous pouvez avoir un timing personnalisé et rendre votre animation interactive et interruptible. C’est très utile lorsque vous réalisez des animations qui sont également interactives avec les actions de l’utilisateur.

    Le geste classique «Glisser pour déverrouiller» et l’animation de suppression / développement de la vue du lecteur (dans l’application Musique) sont des exemples d’animations interactives et interruptibles. Vous pouvez commencer à déplacer une vue avec votre doigt, puis relâchez-la et la vue reviendra à sa position initiale. Vous pouvez également capturer la vue pendant l'animation et continuer à la faire glisser avec votre doigt.

    Voici un exemple simple montrant comment réaliser l'animation à l'aide de UIViewPropertyAnimator :

     laissez newButtonWidth: CGFloat =. 60
    let animator = UIViewPropertyAnimator (durée: 0.3, curve: .linear) {// 1
        self.button.frame = CGRect (x: 0, y: 0, largeur: newButtonWidth, hauteur: newButtonWidth)
        self.button.center = self.view.center
    }
    animator.startAnimation () // 2 

    Voici ce que nous faisons:

    1. Nous appelons l'API UIViewProperty en passant la durée et la courbe d'animation.
    2. Contrairement à l'UIView.animate ci-dessus. Dans les API, l'animation ne démarrera que si vous le spécifiez vous-même, c'est-à-dire que vous avez le contrôle total du processus / du flux complet de l'animation.

    Maintenant, supposons que vous souhaitiez encore plus de contrôle sur les animations. Par exemple, vous souhaitez concevoir et contrôler chaque image de l'animation. Il existe une autre API pour cela, animateKeyframes . Mais avant de nous y plonger, regardons rapidement ce qu'est une image dans une animation.

    Qu'est-ce qu'une image ?

    Collection des modifications / transitions d'image de la vue, depuis le début état dans l'état final, est défini comme animation et chaque position de la vue pendant l'animation est appelée image .

    animateKeyframes

    Cette API fournit un moyen de concevez l’animation de manière à pouvoir définir plusieurs animations avec différents temps et transitions. Après cela, l’API intègre simplement toutes les animations dans une expérience homogène.

    Supposons que nous voulions déplacer notre bouton à l’écran de manière aléatoire. Voyons comment utiliser l'API d'animation d'images clés pour le faire.

     UIView.animateKeyframes (withDuration: 5, // 1
      délai: 0, // 2
      options: .calculationModeLinear, // 3
      animations: {// 4
        UIView.addKeyframe (// 5
          withRelativeStartTime: 0.25, // 6
          durée relative: 0.25) {// 7
            self.button.center = CGPoint (x: self.view.bounds.midX, y: self.view.bounds.maxY) // 8
        }
    
        UIView.addKeyframe (avecRelativeStartTime: 0.5, relativeDuration: 0.25) {
            self.button.center = CGPoint (x: self.view.bounds.width, y: start.y)
        }
    
        UIView.addKeyframe (avecRelativeStartTime: 0.75, relativeDuration: 0.25) {
            self.button.center = start
        }
    }) 

    Voici la répartition:

    1. duration
      Appelez l'IPA en passant la durée de l'animation.
    2. delay
      Durée du retard initial de l'animation. [19659026] options
      Type de courbe d'animation que vous souhaitez appliquer à votre animation d'affichage.
    3. animations
      Bloc contenant toutes les animations d'images clés conçues par le développeur / l'utilisateur.
    4. addKeyFrame
      Appelez l'API pour concevoir chaque animation. Dans notre cas, nous avons défini chaque mouvement du bouton. Nous pouvons avoir autant d'animations que nécessaire, ajoutées au bloc.
    5. relativeStartTime
      Définit l'heure de début de l'animation dans la collection du bloc d'animation.
    6. relativeDuration [19659039] Définit la durée totale de cette animation spécifique.
    7. center
      Dans notre cas, nous modifions simplement la propriété center du bouton pour déplacer le bouton sur l'écran.

    Et voici comment la dernière Les animations ressemblent à:

    CoreAnimation

    Toute animation basée sur UIKit est traduite en interne en animations de base. Ainsi, la structure Core Animation agit en tant que couche de base ou d’ossature pour toute animation UIKit. Par conséquent, toutes les API d'animation UIKit ne sont rien d'autre que des couches encapsulées des API d'animation principales d'une manière facilement consommable ou commode.

    Les API d'animation UIKit ne permettent pas un contrôle important des animations exécutées sur une vue car elles sont principalement utilisées. pour les propriétés animables de la vue. Par conséquent, dans les cas où vous souhaitez contrôler toutes les images de l'animation, il est préférable d'utiliser directement les API d'animation principales sous-jacentes. Vous pouvez également utiliser conjointement les animations UIView et les animations principales.

    UIView + Core Animation

    Voyons comment nous pouvons recréer la même animation de changement de bouton tout en spécifiant la courbe de temporisation à l'aide de UIView et de Core Animation. API.

    Nous pouvons utiliser les fonctions de minutage de CATransaction qui vous permettent de spécifier et de contrôler la courbe d’animation.

    Voyons un exemple d’animation de changement de taille de bouton avec son rayon de coin utilisant La fonction de synchronisation de CATransaction et une combinaison d'animations UIView:

     let oldValue = button.frame.width / 2
    laissez newButtonWidth: CGFloat = 60
    
    / * Faire des animations * /
    CATransaction.begin () // 1
    CATransaction.setAnimationDuration (2.0) // 2
    CATransaction.setAnimationTimingFunction (CAMediaTimingFunction (nom: CAMediaTimingFunctionName.easeInEaseOut)) // 3
    
    // Voir les animations // 4
    UIView.animate (withDurée: 1.0) {
        self.button.frame = CGRect (x: 0, y: 0, largeur: newButtonWidth, hauteur: newButtonWidth)
        self.button.center = self.view.center
    }
    
    // animations de calque
    let cornerAnimation = CABasicAnimation (keyPath: #keyPath (CALayer.cornerRadius)) // 5
    cornerAnimation.fromValue = oldValue // 6
    cornerAnimation.toValue = newButtonWidth / 2 // 7
    
    button.layer.cornerRadius = newButtonWidth / 2 // 8
    button.layer.add (cornerAnimation, pourKey: #keyPath (CALayer.cornerRadius)) // 9
    
    CATransaction.commit () // 10 

    Voici la ventilation:

    1. begin
      Représente le début du bloc de code d'animation.
    2. duration
      Durée globale de l'animation.
    3. ] Curve
      Représente la courbe de synchronisation à appliquer à l'animation.
    4. UIView.animate
      Notre première animation a été modifiée pour changer le cadre du bouton.
    5. CABasicAnimation
      Nous créons l'objet CABasicAnimation en faisant référence au cornerRadius du bouton comme chemin de clé, car nous souhaitons l'animer. De même, si vous souhaitez avoir un contrôle de niveau granulaire sur les animations des images clés, vous pouvez utiliser la classe CAKeyframeAnimation .
    6. fromValue
      Représente la valeur de départ de l'animation, c'est-à-dire la valeur initiale. cornerRadius valeur du bouton d'où doit commencer l'animation.
    7. toValue
      Représente la valeur finale de l'animation, à savoir la valeur finale cornerRadius du bouton où l'animation doit se terminer.
    8. cornerRadius
      Nous devons définir la propriété cornerRadius du bouton avec la valeur finale de l'animation, sinon la valeur cornerRadius du bouton sera automatiquement restaurée. sa valeur initiale à la fin de l'animation.
    9. addAnimation
      Nous attachons l'objet d'animation contenant la configuration de l'ensemble du processus d'animation à la couche en représentant le chemin de clé pour lequel l'animation a besoin. à exécuter.
    10. commit
      Représente la fin du bloc de code d'animation et démarre l'animation.

    Voici à quoi ressemblerait l'animation finale:

    This blog une excellente lecture pour vous aider à créer des animations plus avancées, car elle vous guide clairement dans la plupart des API du framework Core Animation, avec des instructions qui vous guident tout au long du processus.

    UIKitDynamics

    UIKit Dynamics est le moteur physique de UIKit qui permet vous devez ajouter tous les comportements physiques tels que collision, gravité, poussée, accrochage, etc. aux contrôles UIKit.

    UIKitDynamicAnimator

    Il s'agit de la classe admin du cadre UIKit Dynamics qui régule toutes les animations déclenchées par un contrôle d'interface utilisateur donné.

    UIKitDynamicBehavior

    Il vous permet d'ajouter n'importe quel comportement physique à un animateur, ce qui lui permet ensuite de jouer sur la vue associée.

    Différents types de comportements pour UIKitDynamics sont les suivants:

    • UIAttachmen tBehavior
    • UICollisionBehavior
    • UIFieldBehavior
    • UIGravityBehavior
    • UISnapBehavior

  3. L'architecture de UIKitDynamics ressemble à quelque chose comme ceci . Notez que les éléments 1 à 5 peuvent être remplacés par une seule vue.

    Appliquons un comportement physique à notre bouton. Nous verrons comment appliquer la gravité au bouton afin qu'il nous donne l'impression de traiter avec un objet réel.

     var dynamicAnimator: UIDynamicAnimator!
    var gravityBehavior: UIGravityBehavior!
    
    dynamicAnimator = UIDynamicAnimator (referenceView: self.view) // 1
    
    gravityBehavior = UIGravityBehavior (items: [button]) // 2
    dynamicAnimator.addBehavior (gravityBehavior) // 3 

    Voici la ventilation:

    1. UIKitDynamicAnimator
      Nous avons créé un objet UIKitDynamicAnimator qui agit comme un animateur pour animer des animations. Nous avons également passé la vue d'ensemble de notre bouton comme vue de référence.
    2. UIGravityBehavior
      Nous avons créé un objet UIGravityBehavior et transmettons notre bouton aux éléments de la matrice sur lesquels ce comportement est injecté. .
    3. addBehavior
      Nous avons ajouté l'objet gravité à l'animateur.

      Ceci devrait créer une animation comme indiqué ci-dessous:

      Remarquez comment le bouton se détache du centre (sa position d'origine). vers le bas et au-delà.

      Nous devrions dire à l'animateur de considérer le bas de l'écran comme étant le sol. C'est là qu'intervient UICollisionBehavior .

       var dynamicAnimator: UIDynamicAnimator!
      var gravityBehavior: UIGravityBehavior!
      var collisionBehavior: UICollisionBehavior!
      
      dynamicAnimator = UIDynamicAnimator (referenceView: self.view) // 1
      
      gravityBehavior = UIGravityBehavior (items: [button]) // 2
      dynamicAnimator.addBehavior (gravityBehavior) // 3
      
      collisionBehavior = UICollisionBehavior (éléments: [button]) // 4
      collisionBehavior.translatesReferenceBoundsIntoBoundary = true // 5
      dynamicAnimator.addBehavior (collisionBehavior) // 6  
    4. UICollisionBehavior
      Nous avons créé un objet UICollisionBehavior et le long du bouton, de sorte que le comportement est ajouté au comportement. element.
    5. translatesReferenceBoundsIntoBoundary
      L'activation de cette propriété indique à l'animateur de prendre la limite des vues de référence comme fin, qui est le fond de l'écran dans notre cas.
    6. addBehavior
      We ont ajouté le comportement de collision à l'animateur ici.

      Maintenant, notre bouton devrait toucher le sol et rester immobile, comme indiqué ci-dessous:

      C'est plutôt chouette, n'est-ce pas?

      Maintenant, essayons d'ajouter un rebond. effet pour que notre objet se sent plus réel. Pour ce faire, nous allons utiliser la classe UIDynamicItemBehavior .

       var dynamicAnimator: UIDynamicAnimator!
      var gravityBehavior: UIGravityBehavior!
      var collisionBehavior: UICollisionBehavior!
      var bouncingBehavior: UIDynamicItemBehavior!
      
      dynamicAnimator = UIDynamicAnimator (referenceView: self.view) // 1
      
      gravityBehavior = UIGravityBehavior (items: [button]) // 2
      dynamicAnimator.addBehavior (gravityBehavior) // 3
      
      collisionBehavior = UICollisionBehavior (éléments: [button]) // 4
      collisionBehavior.translatesReferenceBoundsIntoBoundary = true // 5
      dynamicAnimator.addBehavior (collisionBehavior) // 6
      
      // Ajout de l'effet de rebond
      bouncingBehavior = UIDynamicItemBehavior (éléments: [button]) // 7
      bouncingBehavior.elasticity = 0,75 // 8
      dynamicAnimator.addBehavior (bouncingBehavior) // 9  
    7. UIDynamicItemBehavior
      Nous avons créé un objet UIDynamicItemBehavior afin que le comportement soit ajouté. Élément.
    8. Élasticité
      La valeur doit être comprise entre 0 et 1; elle représente l'élasticité, c'est-à-dire le nombre de fois que l'objet doit rebondir sur et au sol lorsqu'il est touché. C'est ici que la magie opère – en modifiant cette propriété, vous pouvez différencier différents types d'objets tels que balles, bouteilles, objets durs, etc.
    9. addBehavior
      Nous avons ajouté le comportement de collision à l'animateur. ici

    Maintenant, notre bouton devrait rebondir quand il touche le sol, comme indiqué ci-dessous:

    Ce rapport est très utile et montre tous les comportements UIKitDynamics en action. Il fournit également du code source pour jouer avec chaque comportement. Cela, à mon avis, devrait constituer une liste exhaustive de manières d'effectuer des animations iOS sur des vues!

    Dans la section suivante, nous allons brièvement examiner les outils qui nous aideront à mesurer les performances des animations. Je vous recommanderais également de rechercher des moyens d'optimiser la construction de votre Xcode car cela vous fera gagner un temps considérable en développement.

    Optimisation des performances

    Dans cette section, nous allons examiner mesurer et ajuster les performances des animations iOS. En tant que développeur iOS, vous avez peut-être déjà utilisé des instruments Xcode, tels que les pertes de mémoire et les allocations, pour mesurer les performances de l'ensemble de l'application. De même, il existe des instruments permettant de mesurer les performances des animations.

    Core Animation Instrument

    Essayez l'instrument Core Animation et vous devriez être en mesure de voir le FPS que l'écran de votre application délivre. Il s'agit d'un excellent moyen de mesurer les performances / la vitesse de n'importe quelle animation rendue dans votre application iOS.

    Drawing

    Le nombre d'images par seconde (FPS) est considérablement réduit dans l'application qui affiche un contenu important, comme des images avec des effets tels que des ombres. Dans ce cas, au lieu d’attribuer l’image directement à la propriété d’image de UIImageView essayez de dessiner l’image séparément dans un contexte à l’aide des API Core Graphics. Cela réduit excessivement le temps d'affichage des images en exécutant la logique de décompression des images de manière asynchrone lorsqu'elle est effectuée dans un fil séparé au lieu du fil principal.

    Rastérisation

    La rastérisation est un processus utilisé pour mettre en cache des informations de couche complexes afin que ces vues ne soient pas redessiné chaque fois qu'ils sont rendus. Le redécoupage des vues est la principale cause de la réduction du nombre d'images par seconde et il est donc préférable d'appliquer le rastérisation sur les vues qui seront réutilisées plusieurs fois.

    En conclusion

    En conclusion, j'ai également résumé un liste de ressources utiles pour les animations iOS . Vous pouvez trouver cela très pratique lorsque vous travaillez sur des animations iOS. En outre, vous pouvez également trouver cet ensemble d'outils de conception utile comme étape (de conception) avant de vous plonger dans les animations.

    J'espère avoir pu couvrir autant de sujets que possible entourant les animations iOS. S'il y a quelque chose que j'ai peut-être manqué dans cet article, merci de me le faire savoir dans la section commentaires ci-dessous et je serais heureux de faire l'ajout!

     Smashing Editorial (dm, yk, il)




Source link