CAShapeLayer — co to je, vlastnosti a vytváření tvarů

Autor: IT Sectr Publikováno: 2026-06-12 Doba čtení: 10 min

CAShapeLayer — je podtřída CALayer určená pro hardwarové vykreslování vektorových obrysů na GPU. Na rozdíl od základního CALayer, který pracuje s rastrovými obrázky přes contents, CAShapeLayer vykresluje libovolné tvary zadané přes CGPath bez vytváření samostatného offscreen bufferu. Podle Apple QuartzCore Documentation, 2025 používá CAShapeLayer hardwarovou akceleraci pro vyhlazování hran a podporuje animaci path, strokeStart a strokeEnd. Je to standardní nástroj pro vytváření ikon, indikátorů průběhu a masek v iOS.

Hlavní body

  • CAShapeLayer — podtřída CALayer pro vykreslování vektorových tvarů na GPU přes CGPath.
  • Vykreslování obrysu probíhá hardwarově bez vytváření mezilehlého rastrového bufferu — je rychlejší než Core Graphics.
  • Vlastnosti fillColor, strokeColor, lineWidth, lineCap, lineJoin řídí vzhled tvaru.
  • Animace path umožňuje plynulou změnu jednoho tvaru na druhý — klíčová schopnost pro UI animace.
  • strokeStart a strokeEnd jsou animovány pro vytvoření efektu kreslení obrysu — ideální pro indikátory načítání.

Co je CAShapeLayer?

CAShapeLayer — je specializovaná vrstva pro vykreslování vektorové grafiky, představená v iOS 3.0. Na rozdíl od CALayer, který ukládá rastrový obrázek, CAShapeLayer ukládá matematický popis obrysu — CGPath — a vykresluje jej přímo na GPU. To umožňuje škálování tvaru bez ztráty kvality a animaci jeho vlastností bez překreslování obsahu.

Architektonicky CAShapeLayer dědí všechny schopnosti CALayer: stíny, okraje, transformace, masky. Přidává však specifické vlastnosti pro práci s obrysy: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, miterLimit, strokeStart, strokeEnd a fillRule. Každá z těchto vlastností může být animována pomocí CABasicAnimation.

Podle Apple Documentation používá CAShapeLayer hardwarovou akceleraci při vykreslování. Na rozdíl od kreslení přes Core Graphics v drawRect:, kde CPU vykresluje obrys v rastrovém kontextu, CAShapeLayer posílá příkazy přímo na GPU přes Metal. Výsledek — vyšší výkon, zejména během animace.

CAShapeLayer je zvláště užitečný pro prvky rozhraní, které mění tvar v reakci na akce uživatele: indikátory průběhu, grafy, ikony tab-bar, masky pro animaci zobrazení obsahu.

Jak CAShapeLayer vykresluje obrys na GPU

Proces vykreslování CAShapeLayer se liší od základního CALayer. Místo ukládání rastrového bufferu s pixely posílá CAShapeLayer GPU popis vrcholů obrysu — sadu bodů, Bézierových křivek a segmentů. GPU tento obrys rasterizuje v jednom průchodu, aplikuje barvu výplně a obrysu ve fázi fragment shaderu.

Tento přístup poskytuje dvě výhody: škálování bez ztráty kvality (vektorová grafika zůstává ostrá při jakémkoli rozlišení) a efektivní animaci — při změně path GPU přepočítává pouze změněné pixely, ne celou obrazovku.

Hlavní vlastnosti CAShapeLayer

path — centrální vlastnost CAShapeLayer, přijímající CGPath. Obrys může obsahovat čáry, oblouky, Bézierovy křivky a obdélníky. Vytváří se přes UIBezierPath ve Swift nebo CGPath v Core Graphics. Příklad: UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPath vytváří zaoblený obdélník.

  • fillColor — barva výplně uzavřeného obrysu (CGColor). Pokud nil — bez výplně. Podporuje animaci.
  • strokeColor — barva obrysu. Animuje se spolu s lineWidth, vytváří efekt kreslícího se obrysu.
  • lineWidth — tloušťka čáry obrysu v bodech. Výchozí 1.0. Lze animovat.
  • lineCap — styl zakončení čáry: .butt (rovný řez), .round (zaoblený), .square (obdélníkový s převisem).
  • lineJoin — styl spojení čar: .miter (ostrý úhel), .round (zaoblený), .bevel (seříznutý).
  • strokeStart a strokeEnd — podíl vykresleného obrysu od 0.0 do 1.0. Animace strokeEnd vytváří efekt postupného zobrazení.
  • fillRule — pravidlo výplně protínajících se obrysů: .nonZero (výchozí) nebo .evenOdd.
  • miterLimit — maximální délka hrotu při lineJoin = .miter. Zabraňuje nekonečně dlouhým úhlům.

Vlastnost lineDashPattern umožňuje vytváření přerušovaných čar. Přijímá pole čísel: [6, 3] znamená 6 bodů čáry a 3 body mezery. lineDashPhase nastavuje posun vzoru a může být animována pro efekt pohybující se přerušované čáry.

CAShapeLayer vs CALayer: kdy zvolit který

Volba mezi CAShapeLayer a základním CALayer závisí na typu obsahu. Pokud je prvek obdélníková oblast s pozadím, okrajem a stínem — stačí CALayer. Pokud má prvek libovolný tvar, vyžaduje animaci obrysu nebo škálování bez ztráty kvality — CAShapeLayer je vhodnější.

Výkon se také liší. CALayer s cornerRadius a masksToBounds vytváří offscreen buffer pro ořezávání obsahu, což přidává 2–5 ms na snímek. CAShapeLayer nevyžaduje offscreen buffer — ořezávání probíhá na úrovni vertex shaderu. Pro prvky se složitou maskou může být CAShapeLayer 2–3krát rychlejší.

  • CALayer: obdélníkové prvky, fotografie, video, obsah se zaoblenými rohy (cornerRadius), stíny, okraje.
  • CAShapeLayer: ikony, grafy, ukazatele průběhu, masky libovolného tvaru, animované obrysy, tvary pro animaci zobrazení.
  • CATextLayer: text vyžadující subpixelové vykreslování a ukládání glyfů do mezipaměti.
  • CAGradientLayer: přechodové výplně — kombinuje se s CAShapeLayer přes mask pro vytváření tvarů s přechodem.

Kombinování CAShapeLayer s jinými vrstvami je běžný vzor. Například CAGradientLayer používá CAShapeLayer jako masku pro vytvoření tvaru s přechodovou výplní. Tento přístup poskytuje jak vektorovou kvalitu, tak přechodovou výplň bez ztráty výkonu.

Animace CAShapeLayer: path a stroke

Animace path — jedna z nejsilnějších schopností CAShapeLayer. Pokud mají oba obrysy (počáteční a koncový) stejný počet řídicích bodů a segmentů, Core Animation provádí plynulou interpolaci mezi nimi. Výsledek — efekt morfingu jednoho tvaru do druhého.

Podmínka kompatibility path: počáteční a koncový UIBezierPath musí mít stejnou strukturu — počet volání moveTo, addLine, addCurve a addQuadCurve se musí shodovat. Pokud se struktura liší, animace bude okamžitá, bez interpolace.

Podle Apple WWDC 2024 je kombinace strokeStart a strokeEnd nejčastěji používaným vzorem animace CAShapeLayer. Animace strokeEnd od 0.0 do 1.0 vytváří efekt kreslení obrysu od začátku do konce. Používá se v indikátorech načítání, animacích zobrazení grafů a vlastních přechodech mezi obrazovkami.

Pro vytvoření pulzujícího efektu animujte současně strokeEnd a opacity s různými časovacími funkcemi. Pro efekt pohybující se přerušované čáry animujte lineDashPhase s pevným lineDashPattern. Obě techniky jsou implementovány přes CABasicAnimation bez účasti CPU.

Animace jako maska

CAShapeLayer se často používá jako mask pro jiné vrstvy. Například pro animaci zobrazení obsahu: na začátku je mask.path obdélník nulové velikosti, na konci — plná velikost. Core Animation interpoluje path a obsah se plynule odhalí.

Tento vzor se používá v iOS pro animaci rozbalování karet, zobrazování modálních oken a přechodů mezi view controllery. Na rozdíl od animace alpha poskytuje animace přes masku CAShapeLayer přirozenější efekt zobrazení s libovolným tvarem.

Příklady kódu s CAShapeLayer ve Swift

První příklad — vytvoření kruhového indikátoru průběhu s animací strokeEnd. Toto je standardní prvek UI, který demonstruje hlavní schopnosti CAShapeLayer:

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
}

// Animovat na 75%
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

Druhý příklad — animace morfingu mezi kruhem a čtvercem. Oba UIBezierPath mají kompatibilní strukturu:

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

Třetí příklad — maska s CAShapeLayer pro animaci zobrazení obsahu. Maska se rozšiřuje od středu k okrajům:

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
}

Často kladené otázky

Čím se liší CAShapeLayer od kreslení v drawRect?

drawRect používá CPU pro vykreslování v rastrovém kontextu — je pomalé pro animace. CAShapeLayer vykresluje obrys na GPU, což poskytuje 60 FPS při animaci path, strokeEnd a transformací. Kromě toho CAShapeLayer nevyžaduje překreslení při změně velikosti — tvar se škáluje vektorově.

Proč animace path nefunguje plynule?

Plynulá animace path vyžaduje stejnou strukturu počátečního a koncového UIBezierPath. Počet volání moveTo, addLine, addCurve se musí shodovat. Použijte UIBezierPath se stejným počtem segmentů pro počáteční a koncový tvar.

Jak vytvořit přerušovanou čáru v CAShapeLayer?

Nastavte lineDashPattern — pole čísel střídavě určujících délku čáry a mezery. Například [8, 4] vytváří čáry 8pt s mezerami 4pt. Pro pohybující se přerušovanou čáru animujte lineDashPhase přes CABasicAnimation s lineární časovací funkcí.

Lze použít CAShapeLayer jako masku?

Ano, to je jeden z hlavních scénářů. Přiřaďte CAShapeLayer vlastnosti mask libovolného CALayer, včetně CAGradientLayer a dalších podtříd. Animace path masky vytváří efekt plynulého zobrazení obsahu přes tvar libovolné formy.

Jak vyplnit tvar přechodem přes CAShapeLayer?

Vytvořte CAGradientLayer a nastavte jeho mask = CAShapeLayer s požadovaným path. Přechod bude viditelný pouze uvnitř obrysu masky. Tento vzor kombinuje výhody vektorového tvaru CAShapeLayer s přechodovou výplní CAGradientLayer.

Shrnutí

  • CAShapeLayer — podtřída CALayer pro hardwarové vykreslování vektorových obrysů na GPU přes CGPath.
  • Klíčové vlastnosti: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, strokeStart, strokeEnd.
  • Animace path vytváří morfing tvarů — vyžaduje stejnou strukturu počátečního a koncového obrysu.
  • Animace strokeEnd — standardní vzor pro indikátory průběhu a kreslení obrysů.
  • CAShapeLayer nevyžaduje offscreen buffer pro maskování, na rozdíl od CALayer s masksToBounds.
  • Používá se jako maska pro CAGradientLayer, vytvářející tvary s přechodovou výplní.
  • Pro přerušované čáry použijte lineDashPattern s animací lineDashPhase pro efekt pohybu.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také