Core Animation: mga batayan, CALayer at animasyon sa iOS

May-akda: IT Sectr Nai-publish: 2026-03-01 Oras ng pagbabasa: 8 min

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

  • CALayer ang base na klase ng Core Animation para sa pamamahala ng pagpapakita ng nilalaman sa GPU
  • CABasicAnimation simpleng animasyon ng isang properti ng CALayer mula fromValue hanggang toValue
  • CATransaction pagpapangkat ng mga animasyon sa isang transaksyon na may shared duration at completion
  • CAAnimation abstract base class na pinagmamanaan ng CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup
  • Render server hiwalay na proseso (backboardd) na nag-interpolate ng mga frame ng animasyon sa GPU

Ano ang Core Animation?

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.

Arkitektura ng CALayer

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.

Mga uri ng CALayer

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 batayang animasyon ng mga properti

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.

swift
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 pagpapangkat ng mga animasyon

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).

swift
// 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()
}

Mga halimbawa ng code sa Swift

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.

swift
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

Ano ang pagkakaiba sa pagitan ng Core Animation at UIView.animate?

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.

Ano ang implicit animation sa Core Animation?

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).

Paano i-animate ang custom na properti ng CALayer?

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.

Bakit mas mahusay ang CALayer kaysa UIView para sa animasyon?

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

  • Core Animation low-level na Apple framework para sa CALayer animasyon na may rendering sa GPU
  • CALayer base na klase na may 60+ naa-animate na properti, sumusuporta sa CAShapeLayer, CAGradientLayer, CATextLayer
  • CABasicAnimation animasyon ng isang properti na may fromValue/toValue, idinaragdag sa pamamagitan ng layer.add(animation, forKey:)
  • CATransaction pagpapangkat ng mga animasyon na may shared duration, timingFunction, completionBlock
  • Implicit animation awtomatikong animasyon kapag nagbago ang mga properti ng CALayer (tagal 0.25 s)
  • Presentation layer kasalukuyang estado ng layer sa panahon ng animasyon, ginagamit para basahin ang mga intermediate na halaga
  • Pagganap hanggang 120 FPS sa ProMotion, hanggang 1000 layer sa 60 FPS, 4 byte/pixel

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.

Pag-usapan ang proyekto

Basahin din