CAShapeLayer — wat is het, eigenschappen en vormen maken

Auteur: IT Sectr Gepubliceerd: 2026-06-12 Leestijd: 10 min

CAShapeLayer — is een subklasse van CALayer bedoeld voor het hardwarematig renderen van vectorcontouren op de GPU. In tegenstelling tot de basis CALayer, die werkt met rasterafbeeldingen via contents, rendert CAShapeLayer willekeurige vormen die via CGPath zijn gedefinieerd zonder een aparte offscreen-buffer te creëren. Volgens Apple QuartzCore Documentation, 2025 gebruikt CAShapeLayer hardwareversnelling voor het afvlakken van randen en ondersteunt het animatie van path, strokeStart en strokeEnd. Dit is het standaardinstrument voor het maken van pictogrammen, voortgangsindicatoren en masks in iOS.

Belangrijkste punten

  • CAShapeLayer — subklasse van CALayer voor het renderen van vectorvormen op de GPU via CGPath.
  • Het renderen van contouren gebeurt hardwarematig zonder tussentijdse rasterbuffer — het is sneller dan Core Graphics.
  • Eigenschappen fillColor, strokeColor, lineWidth, lineCap, lineJoin bepalen het uiterlijk van de vorm.
  • Path-animatie laat toe om de ene vorm vloeiend in de andere te laten veranderen — een cruciale mogelijkheid voor UI-animaties.
  • strokeStart en strokeEnd worden geanimeerd om het effect van het tekenen van een contour te creëren — ideaal voor laadindicatoren.

Wat is CAShapeLayer?

CAShapeLayer — is een gespecialiseerde laag voor het renderen van vectorafbeeldingen, geïntroduceerd in iOS 3.0. In tegenstelling tot CALayer, die een rasterafbeelding opslaat, slaat CAShapeLayer de wiskundige beschrijving van een contour op — CGPath — en rendert deze rechtstreeks op de GPU. Dit maakt het mogelijk om de vorm te schalen zonder kwaliteitsverlies en de eigenschappen ervan te animeren zonder de inhoud opnieuw te renderen.

Architecturaal gezien erft CAShapeLayer alle mogelijkheden van CALayer: schaduwen, randen, transformaties, masks. Maar het voegt specifieke eigenschappen toe voor het werken met contouren: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, miterLimit, strokeStart, strokeEnd en fillRule. Elk van deze eigenschappen kan worden geanimeerd via CABasicAnimation.

Volgens Apple Documentation gebruikt CAShapeLayer hardwareversnelling bij het renderen. In tegenstelling tot tekenen via Core Graphics in drawRect:, waar de CPU de contour in een rastercontext rendert, stuurt CAShapeLayer commando's rechtstreeks naar de GPU via Metal. Resultaat — hogere prestaties, vooral tijdens animatie.

CAShapeLayer is vooral nuttig voor interface-elementen die van vorm veranderen als reactie op gebruikersacties: voortgangsindicatoren, grafieken, tab-bar-pictogrammen, masks voor het animeren van het verschijnen van inhoud.

Hoe CAShapeLayer een contour op de GPU rendert

Het renderproces van CAShapeLayer verschilt van de basis CALayer. In plaats van een rasterbuffer met pixels op te slaan, stuurt CAShapeLayer de vertex-beschrijving van de contour naar de GPU — een set punten, Bezier-curven en segmenten. De GPU rasteriseert deze contour in één enkele doorgang, waarbij de vul- en lijnkleur wordt toegepast in de fase van de fragment-shader.

Deze aanpak biedt twee voordelen: schalen zonder kwaliteitsverlies (vectorafbeeldingen blijven scherp bij elke resolutie) en efficiënte animatie — bij wijziging van path herberekent de GPU alleen de gewijzigde pixels, niet het hele scherm.

Belangrijkste eigenschappen van CAShapeLayer

path — de centrale eigenschap van CAShapeLayer, die CGPath accepteert. De contour kan lijnen, bogen, Bezier-curven en rechthoeken bevatten. Wordt gemaakt via UIBezierPath in Swift of CGPath in Core Graphics. Voorbeeld: UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPath maakt een afgeronde rechthoek.

  • fillColor — vulkleur van de gesloten contour (CGColor). Indien nil — geen vulling. Ondersteunt animatie.
  • strokeColor — lijnkleur van de contour. Wordt geanimeerd samen met lineWidth, waardoor een tekenend contoureffect ontstaat.
  • lineWidth — dikte van de lijn in punten. Standaard 1.0. Kan worden geanimeerd.
  • lineCap — stijl van het lijneinde: .butt (rechte snede), .round (afgerond), .square (rechthoekig met uitsteeksel).
  • lineJoin — stijl van lijnverbindingen: .miter (scherpe hoek), .round (afgerond), .bevel (afgeschuind).
  • strokeStart en strokeEnd — aandeel van de getekende contour van 0.0 tot 1.0. Animatie van strokeEnd creëert een geleidelijk verschijningseffect.
  • fillRule — vulregel voor kruisende contouren: .nonZero (standaard) of .evenOdd.
  • miterLimit — maximale lengte van de punt bij lineJoin = .miter. Voorkomt oneindig lange hoeken.

De eigenschap lineDashPattern maakt het mogelijk om stippellijnen te maken. Het accepteert een array van getallen: [6, 3] betekent 6 punten lijn en 3 punten spatie. lineDashPhase bepaalt de verschuiving van het patroon en kan worden geanimeerd voor het effect van een bewegende stippellijn.

CAShapeLayer vs CALayer: wanneer welke kiezen

De keuze tussen CAShapeLayer en de basis CALayer hangt af van het type inhoud. Als het element een rechthoekig gebied is met achtergrond, rand en schaduw — is CALayer voldoende. Als het element een willekeurige vorm heeft, animatie van de contour of schaling zonder kwaliteitsverlies vereist — heeft CAShapeLayer de voorkeur.

Ook de prestaties verschillen. CALayer met cornerRadius en masksToBounds maakt een offscreen-buffer voor het bijsnijden van inhoud, wat 2–5 ms per frame toevoegt. CAShapeLayer heeft geen offscreen-buffer nodig — bijsnijden gebeurt op het niveau van de vertex-shader. Voor elementen met complexe masks kan CAShapeLayer 2–3 keer sneller zijn.

  • CALayer: rechthoekige elementen, foto's, video, inhoud met afgeronde hoeken (cornerRadius), schaduwen, randen.
  • CAShapeLayer: pictogrammen, grafieken, voortgangsbalken, masks met willekeurige vorm, geanimeerde contouren, vormen voor verschijningsanimatie.
  • CATextLayer: tekst die subpixel-rendering en glyph-caching vereist.
  • CAGradientLayer: verloopvullingen — wordt gecombineerd met CAShapeLayer via mask voor het maken van vormen met verloop.

Het combineren van CAShapeLayer met andere lagen is een veelvoorkomend patroon. Bijvoorbeeld, CAGradientLayer gebruikt CAShapeLayer als mask om een vorm met verloopvulling te maken. Deze aanpak biedt zowel vectorkwaliteit als verloopvulling zonder prestatieverlies.

CAShapeLayer-animatie: path en stroke

Path-animatie — een van de krachtigste mogelijkheden van CAShapeLayer. Als beide contouren (begin en eind) hetzelfde aantal controlepunten en segmenten hebben, voert Core Animation een vloeiende interpolatie tussen hen uit. Resultaat — het effect van het vervormen van de ene vorm in de andere.

Voorwaarde voor path-compatibiliteit: de begin- en eind-UIBezierPath moeten dezelfde structuur hebben — het aantal aanroepen van moveTo, addLine, addCurve en addQuadCurve moet overeenkomen. Als de structuur verschilt, zal de animatie onmiddellijk zijn, zonder interpolatie.

Volgens Apple WWDC 2024 is de combinatie van strokeStart en strokeEnd het meest gebruikte animatiepatroon van CAShapeLayer. Animatie van strokeEnd van 0.0 naar 1.0 creëert het effect van het tekenen van een contour van begin tot eind. Dit wordt gebruikt in laadindicatoren, animaties van het verschijnen van grafieken en aangepaste overgangen tussen schermen.

Om een pulseereffect te creëren, animeer je tegelijkertijd strokeEnd en opacity met verschillende timing-functies. Voor het effect van een bewegende stippellijn, animeer je lineDashPhase met een vast lineDashPattern. Beide technieken worden geïmplementeerd via CABasicAnimation zonder tussenkomst van de CPU.

Animatie als mask

CAShapeLayer wordt vaak gebruikt als mask voor andere lagen. Bijvoorbeeld, voor het animeren van het verschijnen van inhoud: in het begin is mask.path een rechthoek met nul-formaat, aan het eind — volledig formaat. Core Animation interpoleert path en de inhoud wordt vloeiend onthuld.

Dit patroon wordt in iOS gebruikt voor het animeren van het uitvouwen van kaarten, het verschijnen van modale vensters en overgangen tussen view controllers. In tegenstelling tot alpha-animatie, geeft animatie via een CAShapeLayer-mask een natuurlijker verschijningseffect met een willekeurige vorm.

Codevoorbeelden met CAShapeLayer in Swift

Eerste voorbeeld — het maken van een ronde voortgangsindicator met strokeEnd-animatie. Dit is een standaard UI-element dat de belangrijkste mogelijkheden van CAShapeLayer demonstreert:

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
}

// Animeer naar 75%
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

Tweede voorbeeld — vervormingsanimatie tussen een cirkel en een vierkant. Beide UIBezierPath hebben een compatibele structuur:

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

Derde voorbeeld — mask met CAShapeLayer voor het animeren van het verschijnen van inhoud. Het mask breidt zich uit van het midden naar de randen:

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
}

Veelgestelde vragen

Hoe verschilt CAShapeLayer van tekenen in drawRect?

drawRect gebruikt de CPU voor rendering in een rastercontext — dit is traag voor animaties. CAShapeLayer rendert de contour op de GPU, wat 60 FPS geeft bij animatie van path, strokeEnd en transformaties. Bovendien vereist CAShapeLayer geen herrendering bij formaatwijzigingen — de vorm wordt vectoriëel geschaald.

Waarom werkt path-animatie niet vloeiend?

Vloeiende path-animatie vereist dezelfde structuur van de begin- en eind-UIBezierPath. Het aantal aanroepen van moveTo, addLine, addCurve moet overeenkomen. Gebruik UIBezierPath met hetzelfde aantal segmenten voor de begin- en eindvorm.

Hoe maak je een stippellijn in CAShapeLayer?

Stel lineDashPattern in — een array van getallen die afwisselend de lengte van lijn en spatie bepalen. Bijvoorbeeld, [8, 4] creëert lijnen van 8pt met spaties van 4pt. Voor een bewegende stippellijn, animeer je lineDashPhase via CABasicAnimation met een lineaire timing-functie.

Kan CAShapeLayer als mask worden gebruikt?

Ja, dit is een van de belangrijkste scenario's. Wijs CAShapeLayer toe aan de eigenschap mask van elke CALayer, inclusief CAGradientLayer en andere subklassen. Animatie van het mask-path creëert het effect van vloeiend verschijnen van inhoud door een vorm met willekeurige vorm.

Hoe vul je een vorm met een verloop via CAShapeLayer?

Maak een CAGradientLayer en stel de mask ervan in op CAShapeLayer met het gewenste path. Het verloop is alleen zichtbaar binnen de contour van het mask. Dit patroon combineert de voordelen van de vectorvorm van CAShapeLayer met de verloopvulling van CAGradientLayer.

Samenvatting

  • CAShapeLayer — subklasse van CALayer voor hardwarematig renderen van vectorcontouren op de GPU via CGPath.
  • Belangrijkste eigenschappen: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, strokeStart, strokeEnd.
  • Path-animatie creëert vormvervorming — vereist dezelfde structuur van begin- en eindcontour.
  • strokeEnd-animatie — standaardpatroon voor voortgangsindicatoren en het tekenen van contouren.
  • CAShapeLayer heeft geen offscreen-buffer nodig voor maskering, in tegenstelling tot CALayer met masksToBounds.
  • Gebruikt als mask voor CAGradientLayer, waarmee vormen met verloopvulling worden gemaakt.
  • Voor stippellijnen gebruik je lineDashPattern met animatie van lineDashPhase voor een bewegingseffect.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook