Core Animation ay isang low-level na animation framework ng Apple na gumagana sa antas ng CALayer at nagbibigay ng rendering ng nilalaman sa GPU. Core Animation ang pundasyon ng lahat ng animasyon sa iOS at macOS: UIKit, AppKit, SceneKit at SpriteKit ay binuo sa ibabaw nito. Ipinapaliwanag ng artikulo ang arkitektura ng CALayer, CABasicAnimation, CATransaction at mga praktikal na teknik.
Mga pangunahing punto
Core Animation ay isang graphical framework ng Apple na lumitaw sa Mac OS X 10.5 Leopard (2007) at na-port sa iOS mula sa unang bersyon ng iPhone OS (2007). Pinamamahalaan ng Core Animation ang komposisyon, animasyon at rendering ng mga layer (CALayer) sa GPU. Bawat UIView sa iOS ay may built-in na CALayer (view.layer) kung saan nagaganap ang lahat ng rendering.
Gumagana ang Core Animation sa prinsipyo ng implicit animation: ang ilang pagbabago sa mga properti ng CALayer ay awtomatikong naa-animate (ina-animate ang CABasicAnimation para sa position, bounds, opacity, backgroundColor). Ang mga implicit-animasyon ay gumagamit ng CATransaction bilang default na may tagal na 0.25 segundo at easeInOut curve.
Ayon sa datos ng Apple WWDC 2024, pinoproseso ng Core Animation ang hanggang 120 FPS sa mga ProMotion device, gamit ang Metal para sa GPU rendering. Ang laki ng tipikal na layer sa memorya ay 4 byte bawat pixel (RGBA) + overhead ~100 byte bawat layer. Inirerekomenda na hindi hihigit sa 1000 layer bawat screen para sa stable na 60 FPS.
CALayer ang pundasyon ng Core Animation. Bawat CALayer ay naglalaman ng bitmap na nilalaman (o referensya sa GPU texture) at tumutukoy ng geometry (bounds, position, anchorPoint, transform, cornerRadius, borderWidth, shadow). Hindi pinoproseso ng layer ang mga touch event para dito ang UIView/UIScrollView. Ang mga layer ay bumubuo ng hierarchy (layer tree) na sumasalamin sa view hierarchy.
Sinusuportahan ng Core Animation ang tatlong layer tree: model layer tree (aktwal na mga properti), presentation layer tree (kasalukuyang display sa panahon ng animasyon) at render tree (data para sa GPU). Ginagamit ang presentation layer para basahin ang mga intermediate na halaga ng animasyon sa real-time.
Ang CALayer ay may mga espesyalisadong subklase: CAShapeLayer (vector graphics), CAGradientLayer (gradient), CATextLayer (teksto), CATiledLayer (malalaking imahe na hinati sa mga tile), CAEAGLLayer/MetalLayer (OpenGL/Metal). Ang CAShapeLayer ang pinakasikat para sa custom na animasyon dahil sa suporta para sa CGPath at animasyon ng strokeStart/strokeEnd.
CABasicAnimation ay isang subklase ng CAAnimation na nag-a-animate ng isang properti ng CALayer mula sa panimulang halaga (fromValue) hanggang sa pangwakas na halaga (toValue) o relatibong pagbabago (byValue). Ang animasyon ay idinaragdag sa layer sa pamamagitan ng layer.add(animation, forKey:) at isinasagawa sa render server nang walang partisipasyon ng app sa bawat frame.
Ang key (keyPath) ay isang string na tumutukoy sa properti: opacity, position, bounds, transform.rotation.z, cornerRadius, shadowOpacity at iba pa. Sinusuportahan ng Core Animation ang 60+ na naa-animate na keyPath. Para sa mga custom na properti, ginagamit ang CATransaction at presentation layer.
import QuartzCore
// CABasicAnimation para sa opacity at cornerRadius
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. Animasyon ng transparency
let fadeAnim = CABasicAnimation(keyPath: "opacity")
fadeAnim.fromValue = 1.0
fadeAnim.toValue = 0.2
fadeAnim.duration = 2.0
fadeAnim.autoreverses = true
fadeAnim.repeatCount = .infinity
// 2. Animasyon ng pagbilog ng sulok
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")
}
// Animasyon ng position na may ease-in-out
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 // ina-update ang model layer
}Mahalaga: CABasicAnimation ay isang pansamantalang display (presentation layer). Pagkatapos ng animasyon, bumalik ang layer sa orihinal na halaga ng model layer. Para ayusin ang pangwakas na estado, itakda ang isRemovedOnCompletion = false, fillMode = .forwards at i-update ang model layer sa mga pangwakas na halaga.
CATransaction ay isang mekanismo para sa pagpapangkat ng mga Core Animation animasyon sa iisang transaksyon. Tinutukoy ng CATransaction.begin() at CATransaction.commit() ang mga hangganan ng transaksyon. Sa loob ng transaksyon, maaaring itakda ang mga shared parameter: duration, timingFunction, completionBlock, disableActions. Ang CATransaction ay pundasyon ng mga implicit-animasyon ng CALayer.
Gumagana ang implicit animation kapag ang properti ng CALayer ay binago sa labas ng animation block: layer.opacity = 0.5. Awtomatikong gumagawa ang Core Animation ng CABasicAnimation na may duration mula sa kasalukuyang CATransaction (default 0.25 s). Para huwag paganahin ang implicit-animation, gamitin ang CATransaction.setDisableActions(true).
// CATransaction pagpapangkat at pagkumpleto
func groupedAnimation() {
CATransaction.begin()
CATransaction.setAnimationDuration(1.5)
CATransaction.setAnimationTimingFunction(
CAMediaTimingFunction(name: .easeOut)
)
CATransaction.setCompletionBlock {
print("All animations completed")
}
// Lahat ng pagbabago sa loob ng transaksyon ay naa-animate na may duration 1.5
layer1.opacity = 0.3
layer2.position = CGPoint(x: 200, y: 300)
layer3.backgroundColor = UIColor.systemRed.cgColor
CATransaction.commit()
}
// Pag-disable ng implicit-animation
func updateWithoutAnimation() {
CATransaction.begin()
CATransaction.setDisableActions(true)
layer.frame = newFrame // walang animasyon
CATransaction.commit()
}
// Animasyon ng mga properti ng CAShapeLayer
func animateProgress(percentage: CGFloat) {
CATransaction.begin()
CATransaction.setAnimationDuration(0.8)
CATransaction.setCompletionBlock {
print("Progress updated to (percentage)%")
}
progressLayer.strokeEnd = percentage / 100.0
CATransaction.commit()
}Ang Core Animation ay nag-i-integrate sa UIKit sa pamamagitan ng UIView layer. Ang halimbawa sa ibaba ay nagpapakita ng animasyon ng CAShapeLayer isang pabilog na progress bar na may animasyon ng haba ng arko at pag-ikot ng layer sa pamamagitan ng CABasicAnimation.
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
}
}
}Ina-animate ng CAShapeLayer ang properti na strokeEnd mula 0 hanggang 1, na lumilikha ng epekto ng “pagpupuno” ng pabilog na progress bar. Ang CATransaction na may tagal na 0.6 at easeOut ay nagpapadulas ng animasyon. Ang layer.lineCap = .round ay nagdaragdag ng bilugan na dulo ng linya para sa mas maayos na hitsura.
Mga madalas itanong
Core Animation ay gumagana sa antas ng CALayer at pinamamahalaan sa pamamagitan ng CABasicAnimation, CATransaction. UIView.animate ay isang high-level na wrapper sa ibabaw ng Core Animation na awtomatikong gumagawa ng CABasicAnimation para sa mga properti ng UIView. Ang Core Animation ay nagbibigay ng mas maraming kontrol: keyPath, timingFunction, fillMode, pagpapangkat sa pamamagitan ng CATransaction.
Implicit animation ay awtomatikong animasyon kapag binago ang naa-animate na properti ng CALayer sa labas ng animation block. Halimbawa, layer.opacity = 0.5 ay gumagawa ng CABasicAnimation na may tagal na 0.25 s. Ang mga implicit-animasyon ay pinamamahalaan sa pamamagitan ng CATransaction at hindi pinapagana sa pamamagitan ng setDisableActions(true).
Para sa mga custom na properti, ipatupad ang action(forKey:) sa CALayer at ibalik ang CAAnimation. O gamitin ang CALayer.display() para sa manual na rendering na may animasyon sa pamamagitan ng CADisplayLink. Para sa mga properti na sumusuporta sa CABasicAnimation, sapat na na tukuyin ang keyPath bilang string.
CALayer ay mas magaan kaysa UIView: walang mga event handler (touches, gestures), hindi lumalahok sa Auto Layout at hindi sumusuporta sa accessibility. Ang tipikal na CALayer ay sumasakop ng ~100 byte kumpara sa ~300+ para sa UIView. Pinoproseso ng Core Animation ang mga layer sa render server sa GPU nang hindi binablock ang main thread.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din