CAShapeLayer — vad är det, egenskaper och skapande av former

Författare: IT Sectr Publicerad: 2026-06-12 Lästid: 10 min

CAShapeLayer — är en underklass av CALayer som är utformad för hårdvarurendering av vektorkonturer på GPU. Till skillnad från grundläggande CALayer som arbetar med rasterbilder via contents, renderar CAShapeLayer godtyckliga former som definieras via CGPath utan att skapa en separat offscreen-buffer. Enligt Apple QuartzCore Documentation, 2025 använder CAShapeLayer hårdvaruacceleration för kantutjämning och stöder animering av path, strokeStart och strokeEnd. Det är ett standardverktyg för att skapa ikoner, förloppsindikatorer och masker i iOS.

Huvudpunkter

  • CAShapeLayer — underklass av CALayer för rendering av vektorformer på GPU via CGPath.
  • Rendering av konturer sker hårdvarumässigt utan mellanliggande rasterbuffer — det är snabbare än Core Graphics.
  • Egenskaper fillColor, strokeColor, lineWidth, lineCap, lineJoin styr utseendet på formen.
  • Path-animering gör att en form smidigt kan omvandlas till en annan — en viktig funktion för UI-animationer.
  • strokeStart och strokeEnd animeras för att skapa en konturritningseffekt — idealisk för laddningsindikatorer.

Vad är CAShapeLayer?

CAShapeLayer — är ett specialiserat lager för rendering av vektorgrafik, introducerat i iOS 3.0. Till skillnad från CALayer som lagrar en rasterbild, lagrar CAShapeLayer den matematiska beskrivningen av konturen — CGPath — och renderar den direkt på GPU. Detta gör att formen kan skalas utan kvalitetsförlust och dess egenskaper animeras utan att innehållet renderas om.

Arkitektoniskt ärver CAShapeLayer alla funktioner från CALayer: skuggor, kanter, transformationer, masker. Men det lägger till specifika egenskaper för arbete med konturer: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, miterLimit, strokeStart, strokeEnd och fillRule. Var och en av dessa egenskaper kan animeras via CABasicAnimation.

Enligt Apple Documentation använder CAShapeLayer hårdvaruacceleration vid rendering. Till skillnad från ritning via Core Graphics i drawRect:, där CPU renderar konturen i ett rastersammanhang, skickar CAShapeLayer kommandon direkt till GPU via Metal. Resultat — högre prestanda, särskilt under animering.

CAShapeLayer är särskilt användbar för gränssnittselement som ändrar form som svar på användaråtgärder: förloppsindikatorer, diagram, tab-bar-ikoner, masker för animering av innehållsvisning.

Hur CAShapeLayer renderar konturer på GPU

Renderingsprocessen för CAShapeLayer skiljer sig från grundläggande CALayer. Istället för att lagra en rasterbuffer med pixlar, skickar CAShapeLayer GPU en vertexbeskrivning av konturen — en uppsättning punkter, Bezier-kurvor och segment. GPU rasteriserar konturen i ett enda pass, applicerar fyllnings- och konturfärgen i fragment-shader-steget.

Denna metod ger två fördelar: skalning utan kvalitetsförlust (vektorgrafik förblir skarp i alla upplösningar) och effektiv animering — när path ändras beräknar GPU endast de ändrade pixlarna, inte hela skärmen.

Huvudegenskaper för CAShapeLayer

path — den centrala egenskapen för CAShapeLayer som tar emot CGPath. Konturen kan innehålla linjer, bågar, Bezier-kurvor och rektanglar. Skapas via UIBezierPath i Swift eller CGPath i Core Graphics. Exempel: UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPath skapar en rundad rektangel.

  • fillColor — fyllningsfärg för sluten kontur (CGColor). Om nil — ingen fyllning. Stöder animering.
  • strokeColor — konturens linjefärg. Animeras tillsammans med lineWidth, vilket skapar en ritande kontureffekt.
  • lineWidth — tjocklek på konturlinjen i punkter. Standard 1.0. Kan animeras.
  • lineCap — stil för linjeslut: .butt (rak skärning), .round (rundad), .square (rektangulär med utskott).
  • lineJoin — stil för linjefogning: .miter (skarp vinkel), .round (rundad), .bevel (avskuren).
  • strokeStart och strokeEnd — andel av ritad kontur från 0.0 till 1.0. Animering av strokeEnd skapar en gradvis visningseffekt.
  • fillRule — fyllningsregel för korsande konturer: .nonZero (standard) eller .evenOdd.
  • miterLimit — maximal längd på spets vid lineJoin = .miter. Förhindrar oändligt långa vinklar.

Egenskapen lineDashPattern gör det möjligt att skapa streckade linjer. Tar emot en matris med tal: [6, 3] betyder 6 punkter linje och 3 punkter mellanrum. lineDashPhase anger mönsterförskjutning och kan animeras för effekt av en rörlig streckad linje.

CAShapeLayer vs CALayer: när ska man välja vilken

Valet mellan CAShapeLayer och grundläggande CALayer beror på innehållstypen. Om elementet är ett rektangulärt område med bakgrund, kant och skugga — räcker CALayer. Om elementet har en godtycklig form, kräver konturanimering eller skalning utan kvalitetsförlust — är CAShapeLayer att föredra.

Prestandan skiljer sig också. CALayer med cornerRadius och masksToBounds skapar en offscreen-buffer för beskärning av innehåll, vilket lägger till 2–5 ms per bildruta. CAShapeLayer kräver ingen offscreen-buffer — beskärning sker på vertex-shader-nivå. För element med komplex mask kan CAShapeLayer vara 2–3 gånger snabbare.

  • CALayer: rektangulära element, foton, video, innehåll med rundade hörn (cornerRadius), skuggor, kanter.
  • CAShapeLayer: ikoner, diagram, förloppsindikatorer, masker med godtycklig form, animerade konturer, former för visningsanimering.
  • CATextLayer: text som kräver subpixel-rendering och glyph-cachning.
  • CAGradientLayer: gradientfyllningar — kombineras med CAShapeLayer via mask för att skapa former med gradient.

Att kombinera CAShapeLayer med andra lager är ett vanligt mönster. Till exempel använder CAGradientLayer CAShapeLayer som mask för att skapa en form med gradientfyllning. Denna metod ger både vektorkvalitet och gradientfyllning utan prestandaförlust.

CAShapeLayer-animering: path och stroke

Path-animering — en av de mest kraftfulla funktionerna i CAShapeLayer. Om båda konturerna (start och slut) har samma antal kontrollpunkter och segment, utför Core Animation en smidig interpolation mellan dem. Resultat — effekten av att en form omvandlas till en annan.

Villkor för path-kompatibilitet: start- och slut-UIBezierPath måste ha samma struktur — antalet anrop till moveTo, addLine, addCurve och addQuadCurve måste matcha. Om strukturen skiljer sig kommer animeringen att vara omedelbar, utan interpolation.

Enligt Apple WWDC 2024 är kombinationen av strokeStart och strokeEnd det mest använda animeringsmönstret för CAShapeLayer. Animering av strokeEnd från 0.0 till 1.0 skapar effekten av att rita konturen från början till slut. Det används i laddningsindikatorer, animeringar av diagramvisning och anpassade övergångar mellan skärmar.

För att skapa en pulserande effekt, animera strokeEnd och opacity samtidigt med olika timingfunktioner. För effekten av en rörlig streckad linje, animera lineDashPhase med fast lineDashPattern. Båda teknikerna implementeras via CABasicAnimation utan CPU-deltagande.

Animering som mask

CAShapeLayer används ofta som mask för andra lager. Till exempel för animering av innehållsvisning: i början är mask.path en rektangel med noll storlek, i slutet — full storlek. Core Animation interpolerar path och innehållet avslöjas smidigt.

Detta mönster används i iOS för animering av kortutvikning, visning av modala fönster och övergångar mellan view controllers. Till skillnad från alpha-animering ger animering via en CAShapeLayer-mask en mer naturlig visningseffekt med godtycklig form.

Kodexempel med CAShapeLayer i Swift

Första exemplet — skapa en cirkulär förloppsindikator med strokeEnd-animering. Detta är ett standard UI-element som visar de viktigaste funktionerna i 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
}

// Animera till 75%
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

Andra exemplet — omvandlingsanimering mellan cirkel och kvadrat. Båda UIBezierPath har en kompatibel struktur:

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

Tredje exemplet — mask med CAShapeLayer för animering av innehållsvisning. Masken expanderar från mitten till kanterna:

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
}

Vanliga frågor

Hur skiljer sig CAShapeLayer från ritning i drawRect?

drawRect använder CPU för rendering i ett rastersammanhang — det är långsamt för animationer. CAShapeLayer renderar konturen på GPU, vilket ger 60 FPS vid animering av path, strokeEnd och transformationer. Dessutom kräver CAShapeLayer ingen omrendering vid storleksändring — formen skalas vektoriellt.

Varför fungerar inte path-animering smidigt?

Smidig path-animering kräver samma struktur för start- och slut-UIBezierPath. Antalet anrop till moveTo, addLine, addCurve måste matcha. Använd UIBezierPath med samma antal segment för start- och slutformen.

Hur skapar man en streckad linje i CAShapeLayer?

Ställ in lineDashPattern — en matris med tal som växelvis anger längden på linje och mellanrum. Till exempel skapar [8, 4] linjer på 8pt med mellanrum på 4pt. För en rörlig streckad linje, animera lineDashPhase via CABasicAnimation med en linjär timingfunktion.

Kan CAShapeLayer användas som mask?

Ja, det är ett av huvudalternativen. Tilldela CAShapeLayer till egenskapen mask för valfri CALayer, inklusive CAGradientLayer och andra underklasser. Animering av maskens path skapar en smidig visningseffekt av innehåll genom en godtycklig form.

Hur fyller man en form med gradient via CAShapeLayer?

Skapa en CAGradientLayer och ställ in dess mask = CAShapeLayer med önskad path. Gradienten syns endast inom maskens kontur. Detta mönster kombinerar fördelarna med CAShapeLayer vektorform och CAGradientLayer gradientfyllning.

Sammanfattning

  • CAShapeLayer — underklass av CALayer för hårdvarurendering av vektorkonturer på GPU via CGPath.
  • Nyckelegenskaper: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, strokeStart, strokeEnd.
  • Path-animering skapar formomvandling — kräver samma struktur för start- och slutkontur.
  • strokeEnd-animering — standardmönster för förloppsindikatorer och konturritning.
  • CAShapeLayer kräver ingen offscreen-buffer för maskering, till skillnad från CALayer med masksToBounds.
  • Används som mask för CAGradientLayer, vilket skapar former med gradientfyllning.
  • För streckade linjer, använd lineDashPattern med animering av lineDashPhase för rörelseeffekt.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också