CAAnimation — clasa de bază abstractă a Core Animation, care definește interfața comună pentru toate tipurile de animații: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition. Articolul explică ierarhia claselor, proprietățile cheie, gruparea animațiilor și exemple practice în Swift.
Principalele
CAAnimation — clasa abstractă Core Animation care definește interfața comună pentru toate animațiile. Implementează protocolul CAMediaTiming (timp, repetare, întoarcere automată) și CAMediaTimingFillMode (comportament înainte/după animație). CAAnimation nu poate fi instanțiată direct — utilizați una dintre subclase: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition sau CAAnimation (prin animationForKeyPath).
Fiecare CAAnimation se adaugă la CALayer prin metoda add(_:forKey:). Parametrul forKey este un identificator unic al animației pe strat. Același keyPath poate avea doar o singură animație activă. Pentru a înlocui o animație, utilizați removeAnimation(forKey:) înainte de a adăuga una nouă.
Potrivit Apple, CAAnimation este o modificare temporară a stratului. După finalizarea animației, presentation layer revine la valorile model layer, dacă nu au fost setate fillMode și isRemovedOnCompletion.
Core Animation oferĄ patru subclase principale CAAnimation, fiecare pentru propriul scenariu de animație. Înțelegerea ierarhiei ajută la alegerea tipului potrivit pentru sarcină.
| Clasă | Destinație | Caracteristici cheie |
|---|---|---|
| CABasicAnimation | Animația unei proprietăți de la A la B | fromValue, toValue, byValue, keyPath |
| CAKeyframeAnimation | Animație pe mai multe cadre cheie | values, keyTimes, path, calculationMode |
| CAAnimationGroup | Gruparea mai multor animații | tablou animations, duration unic |
| CATransition | Tranziție între stările stratului | type (fade/push/moveIn/reveal), subtype, startProgress |
CABasicAnimation — cea mai simplă și populară subclasă. CAKeyframeAnimation este utilizată pentru traiectorii complexe (de exemplu, mișcarea pe o curbă Bezier). CAAnimationGroup lansează mai multe animații în paralel. CATransition — tranziție gata făcută între imagini sau stări ale conținutului.
Protocolul CAMediaTiming — partea fundamentală a CAAnimation. Definește proprietățile temporale de bază: duration (durată), repeatCount (număr de repetări), repeatDuration (durată totală a repetărilor), autoreverses (întoarcere la început), beginTime (timpul de start relativ la părinte), timeOffset (decalaj în cadrul unui ciclu), speed (viteză de redare).
Proprietatea fillMode (CAMediaTimingFillMode) determină afișarea stratului înainte (backwards) și după (forwards) animație. Valori: removed (implicit — revenire la model layer), forwards (rămâne în starea finală), backwards (afișează starea inițială înainte de start), both (combină ambele comportamente). fillMode funcționează doar cu isRemovedOnCompletion = false.
CAAnimation moștenește CAMediaTiming și poate fi încuibată într-o animație părinte (CAAnimationGroup). În acest caz, beginTime se calculează relativ la începutul părintelui, iar duration este limitat de părinte. Speed = 2.0 accelerează animația de două ori.
CAAnimationGroup combină mai multe CAAnimation într-un singur grup. Toate animațiile copil se lansează în paralel, dacă nu este setat beginTime pentru fiecare. Grupul are propriul duration care limitează durata maximă a animațiilor copil. timingFunction al grupului se aplică ca valoare implicită dacă animația copil nu și-a setat propria.
CAKeyframeAnimation animează o proprietate pe mai multe cadre cheie definite de tabloul values. Parametrul keyTimes (tablou NSNumber de la 0 la 1) determină marcajele temporale pentru fiecare cadru. calculationMode specificĄ interpolarea: linear, discrete (fără interpolare), paced (viteză uniformă), cubic (spline), cubicPaced.
import QuartzCore
// CAAnimationGroup — combinație de animații
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 — mișcare pe traiectorie
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 cu valori personalizate
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 // relativ la poziția curentă
layer.add(bounce, forKey: nil)
}CAAnimationGroup execută fade, scale și rotate în paralel cu duration 2.0. CAKeyframeAnimation cu path și calculationMode = .cubicPaced asigură o mișcare uniformă de-a lungul curbei Bezier cu rotație automată (rotationMode = .auto). bounceAnimation folosește isAdditive pentru deplasare relativă.
Exemplul complet CAAnimation pentru o animație complexă a stratului folosind CATransition pentru schimbarea conținutului și CAAnimationGroup pentru pulsație.
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 — tranziție între stări
let transition = CATransition()
transition.type = .fade
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
demoLayer.add(transition, forKey: nil)
// Schimbăm conținutul printr-o tranzacție
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 cu type: .fade creează o tranziție lină între două stări ale backgroundColor. CAAnimationGroup combină scale, opacity și shadowOpacity pentru efectul de pulsație. removeAllAnimations() resetează toate animațiile și readuce stratul la valorile inițiale ale model layer.
Întrebări frecvente
CABasicAnimation animează o proprietate de la valoarea inițială (fromValue) la cea finală (toValue) cu interpolare uniformă. CAKeyframeAnimation vă permite să specificați un tablou de valori intermediare (values) și marcaje temporale (keyTimes) pentru animația neliniară pe cadre cheie, inclusiv mișcarea pe curbă prin path.
CAAnimationGroup este necesar când mai multe animații trebuie să se execute în paralel cu garanția sincronizării: duration-ul grupului limitează toate animațiile copil. Folosiți grupul pentru efecte combinate: scalare + schimbare transparență + rotație simultană.
fillMode determină afișarea stratului înainte (backwards) și după (forwards) animație. Valoarea .forwards lasă stratul în starea finală după terminarea animației (necesită isRemovedOnCompletion = false). .both combină backwards (starea inițială înainte de start) și forwards.
CAAnimation este un obiect de animație (instrucțiune) care se adaugă la CALayer prin layer.add(animation, forKey:). Animația există ca un obiect separat, poate fi reutilizată (prin copiere) și gestionată prin CAMediaTiming. Stratul poate avea mai multe animații cu chei diferite.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și