Core Animation az Apple alacsony szintű animációs keretrendszere, amely CALayer szinten működik és biztosítja a tartalom GPU-n történő megjelenítését. Core Animation az összes animáció alapja iOS és macOS rendszerben: UIKit, AppKit, SceneKit és SpriteKit erre épül. A cikk elmagyarázza a CALayer, CABasicAnimation, CATransaction architektúráját és a gyakorlati technikákat.
Főbb pontok
Core Animation az Apple grafikus keretrendszere, amely a Mac OS X 10.5 Leopard (2007) jelent meg és az iPhone OS (2007) első verziójától kezdve iOS-re is portolták. Core Animation kezeli a rétegek (CALayer) kompozícióját, animációját és megjelenítését a GPU-n. Minden iOS UIView beépített CALayer-rel (view.layer) rendelkezik, amelyen keresztül a teljes megjelenítés történik.
Core Animation az implicit animation elve szerint működik: a CALayer tulajdonságok egyes változásai automatikusan animálódnak (CABasicAnimation-t animál position, bounds, opacity, backgroundColor számára). Az implicit-animációk alapértelmezés szerint CATransaction-t használnak 0.25 másodperces időtartammal és easeInOut görbével.
Az Apple WWDC 2024 adatai szerint a Core Animation akár 120 FPS-t is feldolgoz ProMotion eszközökön, a Metal-t használva GPU megjelenítéshez. Egy tipikus réteg memóriamérete 4 bájt pixelenként (RGBA) + ~100 bájt többlet rétegenként. Stabil 60 FPS-hez legfeljebb 1000 réteg ajánlott képernyőnként.
CALayer a Core Animation alapja. Minden CALayer bitmap tartalmat (vagy GPU textúrára való hivatkozást) tartalmaz és meghatározza a geometriát (bounds, position, anchorPoint, transform, cornerRadius, borderWidth, shadow). A réteg nem dolgozza fel az érintési eseményeket erről a UIView/UIScrollView gondoskodik. A rétegek hierarchiát (layer tree) alkotnak, amely tükrözi a nézet hierarchiát.
Core Animation három rétegfát támogat: model layer tree (tényleges tulajdonságok), presentation layer tree(aktuális megjelenítés animáció közben) és render tree (adatok a GPU-nak). A presentation layer az animáció közbenső értékeinek valós idejű olvasására szolgál.
A CALayer specializált alosztályokkal rendelkezik: CAShapeLayer (vektor grafika), CAGradientLayer (gradiens), CATextLayer (szöveg), CATiledLayer (csempékre osztott nagy képek), CAEAGLLayer/MetalLayer (OpenGL/Metal). A CAShapeLayer a legnépszerűbb egyedi animációkhoz a CGPath támogatásának és a strokeStart/strokeEnd animációnak köszönhetően.
CABasicAnimation a CAAnimation alosztálya, amely egy CALayer tulajdonságot animál a kezdeti értékről (fromValue) a végső értékre (toValue) vagy relatív változásra (byValue). Az animáció a layer.add(animation, forKey:) metódussal adható hozzá a réteghez, és a render server-ben hajtódik végre az alkalmazás minden képkockán történő részvétele nélkül.
A kulcs (keyPath) egy karakterlánc, amely a tulajdonságra mutat: opacity, position, bounds, transform.rotation.z, cornerRadius, shadowOpacity stb. Core Animation 60+ animálható keyPath-et támogat. Egyedi tulajdonságokhoz CATransaction és presentation layer használatos.
import QuartzCore
// CABasicAnimation opacity és cornerRadius számára
func animateLayer() {
let layer = CALayer()
layer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
layer.backgroundColor = UIColor.systemBlue.cgColor
view.layer.addSublayer(layer)
// 1. Átlátszóság animációja
let fadeAnim = CABasicAnimation(keyPath: "opacity")
fadeAnim.fromValue = 1.0
fadeAnim.toValue = 0.2
fadeAnim.duration = 2.0
fadeAnim.autoreverses = true
fadeAnim.repeatCount = .infinity
// 2. Sarkok lekerekítésének animációja
let cornerAnim = CABasicAnimation(keyPath: "cornerRadius")
cornerAnim.fromValue = 0
cornerAnim.toValue = 50
cornerAnim.duration = 2.0
cornerAnim.autoreverses = true
cornerAnim.repeatCount = .infinity
layer.add(fadeAnim, forKey: "fade")
layer.add(cornerAnim, forKey: "corner")
}
// Position animáció ease-in-out-al
func moveLayer(_ layer: CALayer, to point: CGPoint) {
let anim = CABasicAnimation(keyPath: "position")
anim.fromValue = NSValue(cgPoint: layer.position)
anim.toValue = NSValue(cgPoint: point)
anim.duration = 0.6
anim.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
anim.isRemovedOnCompletion = false
anim.fillMode = .forwards
layer.add(anim, forKey: "move")
layer.position = point // model layer frissítése
}Fontos: CABasicAnimation ideiglenes megjelenítés (presentation layer). Az animáció befejezése után a réteg visszatér a model layer kezdeti értékeihez. A végső állapot rögzítéséhez állítsa be az isRemovedOnCompletion = false, fillMode = .forwards értékeket, és frissítse a model layer-t a végső értékekre.
CATransaction a Core Animation animációk egyetlen tranzakcióba történő csoportosításának mechanizmusa. CATransaction.begin() és CATransaction.commit() határozza meg a tranzakció határait. A tranzakción belül közös paraméterek állíthatók be: duration, timingFunction, completionBlock, disableActions. CATransaction a CALayer implicit-animációinak alapja.
Implicit animation akkor működik, amikor a CALayer tulajdonság az animációs blokkon kívül változik: layer.opacity = 0.5. Core Animation automatikusan CABasicAnimation-t hoz létre az aktuális CATransaction duration értékével (alapértelmezés 0.25 mp). Az implicit-animáció kikapcsolásához használja a CATransaction.setDisableActions(true) parancsot.
// CATransaction csoportosítás és befejezés
func groupedAnimation() {
CATransaction.begin()
CATransaction.setAnimationDuration(1.5)
CATransaction.setAnimationTimingFunction(
CAMediaTimingFunction(name: .easeOut)
)
CATransaction.setCompletionBlock {
print("All animations completed")
}
// A tranzakción belüli összes változás 1.5 időtartammal animálódik
layer1.opacity = 0.3
layer2.position = CGPoint(x: 200, y: 300)
layer3.backgroundColor = UIColor.systemRed.cgColor
CATransaction.commit()
}
// Implicit-animáció kikapcsolása
func updateWithoutAnimation() {
CATransaction.begin()
CATransaction.setDisableActions(true)
layer.frame = newFrame // animáció nélkül
CATransaction.commit()
}
// CAShapeLayer tulajdonságok animációja
func animateProgress(percentage: CGFloat) {
CATransaction.begin()
CATransaction.setAnimationDuration(0.8)
CATransaction.setCompletionBlock {
print("Progress updated to (percentage)%")
}
progressLayer.strokeEnd = percentage / 100.0
CATransaction.commit()
}A Core Animation a UIView rétegen keresztül integrálódik a UIKit-kel. Az alábbi példa a CAShapeLayer animációját mutatja be egy kör alakú folyamatjelző sávot az ívhossz animációjával és a réteg forgatásával CABasicAnimation segítségével.
import UIKit
import QuartzCore
class CircularProgressView: UIView {
private let progressLayer = CAShapeLayer()
override func layoutSubviews() {
super.layoutSubviews()
let path = UIBezierPath(
arcCenter: CGPoint(x: bounds.midX, y: bounds.midY),
radius: bounds.width / 2 - 10,
startAngle: -.pi / 2,
endAngle: 3 * .pi / 2,
clockwise: true
)
progressLayer.path = path.cgPath
progressLayer.strokeColor = UIColor.systemBlue.cgColor
progressLayer.lineWidth = 8
progressLayer.fillColor = nil
progressLayer.strokeEnd = 0
progressLayer.lineCap = .round
layer.addSublayer(progressLayer)
}
func setProgress(_ value: CGFloat, animated: Bool = true) {
if animated {
CATransaction.begin()
CATransaction.setAnimationDuration(0.6)
CATransaction.setAnimationTimingFunction(
CAMediaTimingFunction(name: .easeOut)
)
progressLayer.strokeEnd = min(max(value, 0), 1)
CATransaction.commit()
} else {
progressLayer.strokeEnd = value
}
}
}A CAShapeLayer a strokeEnd tulajdonságot animálja 0-ról 1-re, létrehozva a kör alakú folyamatjelző sáv „feltöltésének“ hatását. A 0.6 időtartamú és easeOut görbéjű CATransaction simává teszi az animációt. A layer.lineCap = .round lekerekített végeket ad a vonalnak a rendezettebb megjelenés érdekében.
Gyakran ismételt kérdések
Core Animation CALayer szinten működik és CABasicAnimation, CATransaction segítségével kezelhető. UIView.animate egy magas szintű burkoló a Core Animation felett, amely automatikusan CABasicAnimation-t hoz létre a UIView tulajdonságaihoz. Core Animation több vezérlést biztosít: keyPath, timingFunction, fillMode, csoportosítás CATransaction segítségével.
Implicit animation automatikus animáció, amikor a CALayer animálható tulajdonsága az animációs blokkon kívül változik. Például a layer.opacity = 0.5 CABasicAnimation-t hoz létre 0.25 mp időtartammal. Az implicit-animációk CATransaction segítségével kezelhetők és setDisableActions(true) segítségével kapcsolhatók ki.
Egyedi tulajdonságokhoz implementálja az action(forKey:) metódust a CALayer-ben és adjon vissza CAAnimation-t. Vagy használja a CALayer.display() metódust kézi megjelenítéshez CADisplayLink segítségével. A CABasicAnimation-t támogató tulajdonságoknál elegendő a keyPath megadása karakterláncként.
CALayer könnyebb, mint a UIView: nincsenek eseménykezelői (touches, gesztusok), nem vesz részt az Auto Layout-ban és nem támogatja az accessibility-t. Egy tipikus CALayer ~100 bájtot foglal szemben a UIView ~300+ bájtjával. Core Animation a rétegeket a render server-ben dolgozza fel a GPU-n anélkül, hogy blokkolná a main thread-et.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is