CAShapeLayer — mi ez, tulajdonságok és alakzatok létrehozása

Szerző: IT Sectr Megjelenés: 2026-06-12 Olvasási idő: 10 perc

CAShapeLayer — a CALayer egy alosztálya, amely vektoros kontúrok hardveres megjelenítésére szolgál a GPU-n. Ellentétben az alap CALayer-rel, amely raszterképekkel dolgozik a contents-en keresztül, a CAShapeLayer a CGPath-en keresztül megadott tetszőleges alakzatokat jelenít meg külön offscreen buffer létrehozása nélkül. A Apple QuartzCore Documentation, 2025 szerint a CAShapeLayer hardveres gyorsítást használ az élek simításához és támogatja a path, strokeStart és strokeEnd animációját. Ez a szabványos eszköz ikonok, folyamatjelzők és maszkok létrehozására iOS-ben.

Főbb pontok

  • CAShapeLayer — a CALayer alosztálya vektoralakzatok GPU-n történő megjelenítéséhez CGPath-en keresztül.
  • A kontúr megjelenítése hardveresen történik köztes raszter buffer nélkül — ez gyorsabb, mint a Core Graphics.
  • A tulajdonságok fillColor, strokeColor, lineWidth, lineCap, lineJoin vezérlik az alakzat megjelenését.
  • A path animáció lehetővé teszi az egyik alakzat sima átalakítását egy másikba — kulcsfontosságú képesség az UI animációkhoz.
  • A strokeStart és strokeEnd animálva van a kontúr rajzolásának effektusához — ideális a betöltésjelzőkhöz.

Mi az a CAShapeLayer?

CAShapeLayer — egy specializált réteg vektorgrafika megjelenítésére, amely az iOS 3.0-ban került bevezetésre. Ellentétben a CALayer-rel, amely raszterképet tárol, a CAShapeLayer a kontúr matematikai leírását — CGPath — tárolja, és közvetlenül a GPU-n jeleníti meg. Ez lehetővé teszi az alakzat méretezését minőségveszteség nélkül és tulajdonságainak animálását a tartalom újrarajzolása nélkül.

Architekturálisan a CAShapeLayer örökli a CALayer összes képességét: árnyékok, határok, transzformációk, maszkok. De specifikus tulajdonságokat ad hozzá a kontúrokkal való munkához: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, miterLimit, strokeStart, strokeEnd és fillRule. Ezen tulajdonságok mindegyike animálható a CABasicAnimation segítségével.

A Apple Documentation szerint a CAShapeLayer hardveres gyorsítást használ a megjelenítés során. Ellentétben a Core Graphics segítségével történő rajzolással a drawRect:-ben, ahol a CPU raszterkontextusban jeleníti meg a kontúrt, a CAShapeLayer közvetlenül a GPU-nak küld parancsokat a Metal-on keresztül. Eredmény — magasabb teljesítmény, különösen animáció közben.

A CAShapeLayer különösen hasznos azokhoz a felületi elemekhez, amelyek a felhasználói műveletekre reagálva változtatják alakjukat: folyamatjelzők, grafikonok, tab-bar ikonok, maszkok a tartalom megjelenésének animálásához.

Hogyan jeleníti meg a CAShapeLayer a kontúrt a GPU-n

A CAShapeLayer megjelenítési folyamata eltér az alap CALayer-től. Ahelyett, hogy raszterbuffert tárolna pixelekkel, a CAShapeLayer a kontúr csúcsleírását küldi a GPU-nak — pontok, Bezier-görbék és szegmensek halmazát. A GPU ezt a kontúrt egyetlen menetben raszterizálja, alkalmazva a kitöltés és a vonal színét a fragment shader fázisában.

Ez a megközelítés két előnyt kínál: méretezés minőségveszteség nélkül (a vektorgrafika bármilyen felbontásban éles marad) és hatékony animáció — a path változásakor a GPU csak a megváltozott pixeleket számolja újra, nem a teljes képernyőt.

A CAShapeLayer fő tulajdonságai

path — a CAShapeLayer központi tulajdonsága, amely CGPath-et fogad. A kontúr tartalmazhat vonalakat, íveket, Bezier-görbéket és téglalapokat. Swift-ben UIBezierPath-en vagy Core Graphics-ben CGPath-en keresztül hozható létre. Példa: UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPath lekerekített téglalapot hoz létre.

  • fillColor — a zárt kontúr kitöltési színe (CGColor). Ha nil — nincs kitöltés. Támogatja az animációt.
  • strokeColor — a kontúr vonal színe. A lineWidth-val együtt animálva rajzoló kontúr effektust hoz létre.
  • lineWidth — a vonal vastagsága pontokban. Alapértelmezett 1.0. Animálható.
  • lineCap — a vonal végének stílusa: .butt (egyenes vágás), .round (lekerekített), .square (téglalap alakú kiemelkedéssel).
  • lineJoin — a vonalak csatlakozásának stílusa: .miter (éles szög), .round (lekerekített), .bevel (levágott).
  • strokeStart és strokeEnd — a megrajzolt kontúr aránya 0.0-tól 1.0-ig. A strokeEnd animációja fokozatos megjelenési effektust hoz létre.
  • fillRule — a metsző kontúrok kitöltési szabálya: .nonZero (alapértelmezett) vagy .evenOdd.
  • miterLimit — a csúcs maximális hossza lineJoin = .miter esetén. Megakadályozza a végtelen hosszú szögeket.

A lineDashPattern tulajdonság lehetővé teszi szaggatott vonalak létrehozását. Számok tömbjét fogadja: [6, 3] 6 pont vonalat és 3 pont szóközt jelent. A lineDashPhase a minta eltolását állítja be és animálható a mozgó szaggatott vonal effektusához.

CAShapeLayer vs CALayer: mikor melyiket válasszuk

A választás a CAShapeLayer és az alap CALayer között a tartalom típusától függ. Ha az elem egy téglalap alakú terület háttérrel, határral és árnyékkal — a CALayer elegendő. Ha az elem tetszőleges alakú, kontúr animációt vagy minőségveszteség nélküli méretezést igényel — a CAShapeLayer előnyösebb.

A teljesítmény is eltér. A cornerRadius és masksToBounds tulajdonságokkal rendelkező CALayer offscreen buffert hoz létre a tartalom levágásához, ami képkockánként 2–5 ms-ot ad hozzá. A CAShapeLayer nem igényel offscreen buffert — a levágás a vertex shader szintjén történik. Összetett maszkkal rendelkező elemeknél a CAShapeLayer 2–3-szor gyorsabb lehet.

  • CALayer: téglalap alakú elemek, fényképek, videó, lekerekített sarkú tartalom (cornerRadius), árnyékok, határok.
  • CAShapeLayer: ikonok, grafikonok, folyamatjelző sávok, tetszőleges alakú maszkok, animált kontúrok, alakzatok megjelenési animációhoz.
  • CATextLayer: szubpixel megjelenítést és glyph gyorsítótárazást igénylő szöveg.
  • CAGradientLayer: gradient kitöltések — a CAShapeLayer-rel kombinálva mask segítségével gradientes alakzatok létrehozásához.

A CAShapeLayer kombinálása más rétegekkel gyakori minta. Például a CAGradientLayer a CAShapeLayer-t használja maszkként egy gradientes kitöltésű alakzat létrehozásához. Ez a megközelítés mind vektoros minőséget, mind gradientes kitöltést biztosít teljesítményveszteség nélkül.

CAShapeLayer animáció: path és stroke

Path animáció — a CAShapeLayer egyik legerősebb képessége. Ha mindkét kontúr (kezdeti és végső) azonos számú vezérlőponttal és szegmenssel rendelkezik, a Core Animation sima interpolációt végez közöttük. Eredmény — az egyik alakzat átalakulásának effektusa a másikba.

A path kompatibilitás feltétele: a kezdeti és végső UIBezierPath azonos szerkezetű kell legyen — a moveTo, addLine, addCurve és addQuadCurve hívások számának egyeznie kell. Ha a szerkezet eltér, az animáció azonnali, interpoláció nélkül történik.

A Apple WWDC 2024 szerint a strokeStart és strokeEnd kombinációja a leggyakrabban használt CAShapeLayer animációs minta. A strokeEnd animációja 0.0-tól 1.0-ig a kontúr elejétől a végéig történő rajzolásának effektusát hozza létre. Ezt használják betöltésjelzőkben, grafikonok megjelenési animációiban és egyéni átmenetekben a képernyők között.

Pulzáló effektus létrehozásához animáld egyszerre a strokeEnd és opacity tulajdonságokat különböző időzítési függvényekkel. A mozgó szaggatott vonal effektusához animáld a lineDashPhase-t fix lineDashPattern mellett. Mindkét technika CABasicAnimation segítségével valósítható meg CPU részvétel nélkül.

Animáció maszkként

A CAShapeLayer gyakran használatos maskként más rétegekhez. Például a tartalom megjelenésének animálásához: kezdetben a mask.path egy nulla méretű téglalap, a végén — teljes méret. A Core Animation interpolálja a path-ot, és a tartalom simán feltárul.

Ezt a mintát iOS-ben használják kártyák kinyílásának, modális ablakok megjelenésének és view controller-ek közötti átmenetek animálására. Az alpha animációval ellentétben a CAShapeLayer maszkon keresztüli animáció természetesebb megjelenési effektust biztosít tetszőleges alakzattal.

Kódpéldák CAShapeLayer-rel Swift-ben

Első példa — kör alakú folyamatjelző létrehozása strokeEnd animációval. Ez egy szabványos UI elem, amely bemutatja a CAShapeLayer fő képességeit:

swift
func createProgressIndicator(in view: UIView) -> CAShapeLayer {
    let circlePath = UIBezierPath(
        arcCenter: CGPoint(x: 50, y: 50),
        radius: 40,
        startAngle: -.pi / 2,
        endAngle: 3 * .pi / 2,
        clockwise: true
    )

    let trackLayer = CAShapeLayer()
    trackLayer.path = circlePath.cgPath
    trackLayer.strokeColor = UIColor.systemGray5.cgColor
    trackLayer.fillColor = nil
    trackLayer.lineWidth = 8
    view.layer.addSublayer(trackLayer)

    let progressLayer = CAShapeLayer()
    progressLayer.path = circlePath.cgPath
    progressLayer.strokeColor = UIColor.systemBlue.cgColor
    progressLayer.fillColor = nil
    progressLayer.lineWidth = 8
    progressLayer.lineCap = .round
    progressLayer.strokeEnd = 0
    view.layer.addSublayer(progressLayer)

    return progressLayer
}

// Animáció 75%-ig
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

Második példa — animált átalakulás kör és négyzet között. Mindkét UIBezierPath kompatibilis szerkezettel rendelkezik:

swift
let morphLayer = CAShapeLayer()
morphLayer.fillColor = UIColor.systemPurple.cgColor
morphLayer.frame = rect

let circlePath = UIBezierPath(roundedRect: rect, cornerRadius: rect.width / 2)
let squarePath = UIBezierPath(roundedRect: rect, cornerRadius: 0)
morphLayer.path = circlePath.cgPath

let morphAnimation = CABasicAnimation(keyPath: "path")
morphAnimation.toValue = squarePath.cgPath
morphAnimation.duration = 0.6
morphAnimation.autoreverses = true
morphAnimation.repeatCount = .infinity
morphLayer.add(morphAnimation, forKey: "morph")

Harmadik példa — maszk CAShapeLayer-rel a tartalom megjelenésének animálásához. A maszk a középponttól a szélek felé terjed:

swift
func revealContent(_ view: UIView) {
    let maskLayer = CAShapeLayer()
    let size = view.bounds.size.width * 1.5
    let center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)

    let initialPath = UIBezierPath(arcCenter: center, radius: 0, startAngle: 0, endAngle: .pi * 2, clockwise: true)
    let finalPath = UIBezierPath(arcCenter: center, radius: size, startAngle: 0, endAngle: .pi * 2, clockwise: true)

    maskLayer.path = initialPath.cgPath
    view.layer.mask = maskLayer

    let animation = CABasicAnimation(keyPath: "path")
    animation.toValue = finalPath.cgPath
    animation.duration = 0.4
    animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
    maskLayer.add(animation, forKey: "reveal")
    maskLayer.path = finalPath.cgPath
}

Gyakran Ismételt Kérdések

Miben különbözik a CAShapeLayer a drawRect-ben történő rajzolástól?

drawRect a CPU-t használja a megjelenítéshez raszterkontextusban — ez lassú az animációkhoz. A CAShapeLayer a kontúrt a GPU-n jeleníti meg, ami 60 FPS-t biztosít a path, strokeEnd és transzformációs animációknál. Ezenkívül a CAShapeLayer nem igényel újrarajzolást méretváltozáskor — az alakzat vektorosan méreteződik.

Miért nem működik simán a path animáció?

A sima path animáció megköveteli a kezdeti és végső UIBezierPath azonos szerkezetét. A moveTo, addLine, addCurve hívások számának egyeznie kell. Használj azonos számú szegmensű UIBezierPath-et a kezdeti és végső alakzathoz.

Hogyan hozzunk létre szaggatott vonalat a CAShapeLayer-ben?

Állítsd be a lineDashPattern tulajdonságot — egy számokból álló tömböt, amely felváltva határozza meg a vonal és a szóköz hosszát. Például a [8, 4] 8pt vonalakat hoz létre 4pt szóközökkel. Mozgó szaggatott vonalhoz animáld a lineDashPhase-t CABasicAnimation segítségével lineáris időzítési függvénnyel.

Használható a CAShapeLayer maszkként?

Igen, ez az egyik fő forgatókönyv. Rendeld hozzá a CAShapeLayer-t bármely CALayer mask tulajdonságához, beleértve a CAGradientLayer-t és más alosztályokat. A maszk path animációja a tartalom sima megjelenésének effektusát hozza létre tetszőleges alakzaton keresztül.

Hogyan töltsünk ki egy alakzatot gradiennel a CAShapeLayer-en keresztül?

Hozz létre egy CAGradientLayer-t és állítsd be a mask tulajdonságát = CAShapeLayer a kívánt path-pal. A gradiens csak a maszk kontúrján belül lesz látható. Ez a minta egyesíti a CAShapeLayer vektoralakzatának előnyeit a CAGradientLayer gradientes kitöltésével.

Összefoglalás

  • CAShapeLayer — a CALayer alosztálya vektoros kontúrok hardveres GPU-n történő megjelenítéséhez CGPath-en keresztül.
  • Kulcs tulajdonságok: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, strokeStart, strokeEnd.
  • A path animáció alakzatátalakulást hoz létre — a kezdeti és végső kontúr azonos szerkezetét igényli.
  • A strokeEnd animáció — szabványos minta folyamatjelzőkhöz és kontúrok rajzolásához.
  • A CAShapeLayer nem igényel offscreen buffert a maszkoláshoz, ellentétben a CALayer masksToBounds tulajdonságával.
  • Maszkként használatos a CAGradientLayer-hez, gradientes kitöltésű alakzatokat létrehozva.
  • Szaggatott vonalakhoz használd a lineDashPattern tulajdonságot a lineDashPhase animációval a mozgás effektusához.

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.

Projekt megbeszélése

Olvassa el is