CAAnimation est une classe de base abstraite de Core Animation qui définit l'interface commune pour tous les types d'animations : CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition. L'article explique la hiérarchie des classes, les propriétés clés, le regroupement d'animations et des exemples pratiques en Swift.
Points clés
CAAnimation est une classe abstraite de Core Animation qui définit l'interface commune pour toutes les animations. Elle implémente le protocole CAMediaTiming (durée, répétition, auto-inversion) et CAMediaTimingFillMode (comportement avant/après l'animation). CAAnimation ne peut pas être instanciée directement — utilisez l'une de ses sous-classes : CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition ou CAAnimation (via animationForKeyPath).
Chaque CAAnimation est ajoutée à un CALayer via la méthode add(_:forKey:). Le paramètre forKey est un identifiant unique d'animation sur la couche. Un keyPath ne peut avoir qu'une seule animation active. Pour remplacer une animation, utilisez removeAnimation(forKey:) avant d'en ajouter une nouvelle.
Selon Apple, CAAnimation est une modification "temporaire" de la couche. Une fois l'animation terminée, la couche de présentation revient aux valeurs de la couche modèle si fillMode et isRemovedOnCompletion ne sont pas définis.
Core Animation fournit quatre sous-classes principales de CAAnimation, chacune pour son propre scénario d'animation. Comprendre la hiérarchie aide à choisir le type approprié pour la tâche.
| Classe | Objectif | Caractéristiques principales |
|---|---|---|
| CABasicAnimation | Anime une propriété de A à B | fromValue, toValue, byValue, keyPath |
| CAKeyframeAnimation | Animation sur plusieurs images clés | values, keyTimes, path, calculationMode |
| CAAnimationGroup | Regroupe plusieurs animations | tableau animations, duration unique |
| CATransition | Transition entre états de couche | type (fade/push/moveIn/reveal), subtype, startProgress |
CABasicAnimation est la sous-classe la plus simple et la plus populaire. CAKeyframeAnimation est utilisée pour les trajectoires complexes (par exemple, mouvement le long d'une courbe de Bézier). CAAnimationGroup exécute plusieurs animations en parallèle. CATransition est une transition prête à l'emploi entre des images ou des états de contenu.
Le protocole CAMediaTiming est un élément fondamental de CAAnimation. Il définit les propriétés temporelles de base : duration, repeatCount, repeatDuration, autoreverses, beginTime (temps de début relatif au parent), timeOffset (décalage au sein d'un cycle), speed (vitesse de lecture).
La propriété fillMode (CAMediaTimingFillMode) détermine l'affichage de la couche avant (backwards) et après (forwards) l'animation. Valeurs : removed (par défaut — retour à la couche modèle), forwards (reste dans l'état final), backwards (affiche l'état initial avant le début), both (combine les deux comportements). fillMode fonctionne uniquement lorsque isRemovedOnCompletion = false.
CAAnimation hérite de CAMediaTiming et peut être imbriquée dans une animation parente (CAAnimationGroup). Dans ce cas, beginTime est calculé par rapport au début du parent, et duration est limitée par la durée du parent. Speed = 2.0 double la vitesse de l'animation.
CAAnimationGroup combine plusieurs instances de CAAnimation en un seul groupe. Toutes les animations filles démarrent en parallèle à moins que beginTime ne soit défini pour chacune. Le groupe a sa propre duration, qui limite la durée maximale des animations filles. La timingFunction du groupe est utilisée comme valeur par défaut si une animation fille ne définit pas la sienne.
CAKeyframeAnimation anime une propriété sur plusieurs images clés, définies par un tableau de values. Le paramètre keyTimes (tableau de NSNumber de 0 à 1) définit les horodatages pour chaque image. calculationMode spécifie l'interpolation : linear, discrete (sans interpolation), paced (vitesse uniforme), cubic (spline), cubicPaced.
import QuartzCore
// CAAnimationGroup — combinaison d'animations
func complexLayerAnimation(_ layer: CALayer) {
let fade = CABasicAnimation(keyPath: "opacity")
fade.fromValue = 1.0
fade.toValue = 0.3
let scale = CABasicAnimation(keyPath: "transform.scale")
scale.fromValue = 1.0
scale.toValue = 1.5
let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
rotate.fromValue = 0
rotate.toValue = Double.pi * 2
let group = CAAnimationGroup()
group.animations = [fade, scale, rotate]
group.duration = 2.0
group.repeatCount = .infinity
group.autoreverses = true
layer.add(group, forKey: "pulse")
}
// CAKeyframeAnimation — mouvement sur trajectoire
func animateAlongPath(_ layer: CALayer) {
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addCurve(
to: CGPoint(x: 200, y: 300),
controlPoint1: CGPoint(x: 100, y: 0),
controlPoint2: CGPoint(x: 100, y: 300)
)
let anim = CAKeyframeAnimation(keyPath: "position")
anim.path = path.cgPath
anim.duration = 1.5
anim.calculationMode = .cubicPaced
anim.rotationMode = .auto
anim.fillMode = .forwards
anim.isRemovedOnCompletion = false
layer.add(anim, forKey: "pathAnim")
layer.position = CGPoint(x: 200, y: 300)
}
// CAKeyframeAnimation avec valeurs personnalisées
func bounceAnimation(_ layer: CALayer) {
let bounce = CAKeyframeAnimation(keyPath: "position.y")
bounce.values = [0, -50, 0, -25, 0, -10, 0]
bounce.keyTimes = [0, 0.15, 0.3, 0.45, 0.6, 0.8, 1.0]
bounce.duration = 0.8
bounce.timingFunction = CAMediaTimingFunction(name: .easeOut)
bounce.isAdditive = true // relatif à la position actuelle
layer.add(bounce, forKey: nil)
}CAAnimationGroup exécute fade, scale et rotate en parallèle avec une durée de 2,0. CAKeyframeAnimation avec path et calculationMode = .cubicPaced assure un mouvement uniforme le long d'une courbe de Bézier avec rotation automatique (rotationMode = .auto). bounceAnimation utilise isAdditive pour le décalage relatif.
Un exemple complet de CAAnimation pour une animation complexe de couche utilisant CATransition pour le changement de contenu et CAAnimationGroup pour les effets de pulsation.
import UIKit
import QuartzCore
class AnimationDemoView: UIView {
private let demoLayer = CALayer()
private var currentColor: CGColor = UIColor.systemBlue.cgColor
override func layoutSubviews() {
super.layoutSubviews()
demoLayer.frame = CGRect(x: bounds.midX - 40, y: bounds.midY - 40,
width: 80, height: 80)
demoLayer.backgroundColor = currentColor
demoLayer.cornerRadius = 12
layer.addSublayer(demoLayer)
}
func animateTransition() {
// CATransition — transition entre états
let transition = CATransition()
transition.type = .fade
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
demoLayer.add(transition, forKey: nil)
// Changer le contenu via transaction
currentColor = currentColor == UIColor.systemBlue.cgColor
? UIColor.systemRed.cgColor
: UIColor.systemBlue.cgColor
demoLayer.backgroundColor = currentColor
}
func startPulse() {
let scaleUp = CABasicAnimation(keyPath: "transform.scale")
scaleUp.fromValue = 1.0
scaleUp.toValue = 1.3
let fadeOut = CABasicAnimation(keyPath: "opacity")
fadeOut.fromValue = 1.0
fadeOut.toValue = 0.6
let glow = CABasicAnimation(keyPath: "shadowOpacity")
glow.fromValue = 0.0
glow.toValue = 0.8
let group = CAAnimationGroup()
group.animations = [scaleUp, fadeOut, glow]
group.duration = 1.2
group.autoreverses = true
group.repeatCount = .infinity
group.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
demoLayer.add(group, forKey: "pulse")
}
func stopAnimations() {
demoLayer.removeAllAnimations()
demoLayer.transform = CATransform3DIdentity
demoLayer.opacity = 1.0
demoLayer.shadowOpacity = 0.0
}
}CATransition avec type: .fade crée une transition fluide entre deux états de backgroundColor. CAAnimationGroup combine scale, opacity et shadowOpacity pour un effet de pulsation. removeAllAnimations() annule toutes les animations et ramène la couche à ses valeurs originales de la couche modèle.
Questions fréquentes
CABasicAnimation anime une propriété d'une valeur initiale (fromValue) à une valeur finale (toValue) avec une interpolation uniforme. CAKeyframeAnimation permet de spécifier un tableau de valeurs intermédiaires (values) et d'horodatages (keyTimes) pour une animation non linéaire par images clés, y compris un mouvement basé sur une courbe via path.
CAAnimationGroup est nécessaire lorsque plusieurs animations doivent s'exécuter en parallèle avec une synchronisation garantie : la durée du groupe limite toutes les animations filles. Utilisez group pour des effets combinés : mise à l'échelle + changement d'opacité + rotation simultanément.
fillMode détermine l'affichage de la couche avant (backwards) et après (forwards) l'animation. La valeur .forwards maintient la couche dans l'état final après la fin de l'animation (nécessite isRemovedOnCompletion = false). .both combine backwards (état initial avant le début) et forwards.
CAAnimation est un objet d'animation (instruction) qui est ajouté à un CALayer via layer.add(animation, forKey:). L'animation existe en tant qu'objet séparé, peut être réutilisée (par copie) et est gérée via CAMediaTiming. Une couche peut avoir plusieurs animations avec différentes clés.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi