Layer — is een abstractie van grafische inhoud die de visuele weergave van interface-elementen in mobiele apps beheert. In tegenstelling tot UIView verwerkt layer geen aanraakgebeurtenissen en neemt het niet deel aan Auto Layout — zijn taak is uitsluitend rendering, animatie en pixelcompositie. Volgens Apple QuartzCore Documentation, 2025 heeft elke UIView in iOS een bijbehorende CALayer die feitelijk het tekenen en animeren beheert. Inzicht in de opbouw van lagen stelt de ontwikkelaar in staat om de renderingprestaties op het niveau van individuele pixels te controleren.
Belangrijkste
Layer — is een laag-niveau object van het grafische systeem dat de rasterafbeelding van een schermfragment opslaat en de visuele attributen ervan beheert: positie, grootte, rotatie, transparantie, schaduw en kleur. In iOS heeft elke UIView een ingebouwde CALayer, toegankelijk via de eigenschap layer. De ontwikkelaar kan direct met layer werken, zonder UIView, voor fijnafstemming van de rendering.
De architectuur van lagen volgt het Model-View-Controller-patroon, waarbij CALayer de rol van Model speelt — het slaat de status van visuele eigenschappen op. Core Animation is de Controller die de animatie van overgangen tussen toestanden beheert. View (UIView) — een optionele wrapper die aanraakverwerking en deelname aan Auto Layout toevoegt.
Volgens Apple WWDC 2024 gebruikt de moderne rendering-pipeline van iOS Metal voor laagcompositie. Elke CALayer wordt in een aparte buffer getekend, waarna Core Animation alle buffers samenvoegt tot het uiteindelijke beeld, rekening houdend met transparantie en blending-modi.
In Android zijn de tegenhangers van lagen View en achtergrond-Drawables, maar direct werken met grafische lagen is beschikbaar via Canvas en RenderNode in Android 10+. Het begrijpen van het concept layer is belangrijk voor het optimaliseren van rendering op beide platforms.
Het belangrijkste verschil zit in het verantwoordelijkheidsgebied. View is verantwoordelijk voor gebruikersinvoer (aanrakingen, gebaren), positionering (Auto Layout, frame) en levenscyclus. Layer is uitsluitend verantwoordelijk voor de visuele weergave: het renderen van inhoud, het animeren van eigenschappen en de compositie met andere lagen.
Deze scheiding maakt het mogelijk om de rasterweergave van de laag onafhankelijk van View te cachen. Als de laag niet verandert, gebruikt Core Animation de gecachte frame zonder drawRect aan te roepen. Voor statische elementen levert dit een aanzienlijke prestatieverbetering op zonder codewijzigingen.
iOS biedt een rijke hiërarchie van klassen die overerven van CALayer. Elke subklasse is geoptimaliseerd voor een specifiek scenario: het weergeven van tekst, vectorafbeeldingen, gradiënten of 3D-transformaties. De keuze van het juiste laagtype heeft directe invloed op de renderingprestaties.
In Android is het concept van lagen geïmplementeerd via RenderNode, ViewLayer en HardwareRenderer. Vanaf Android 5.0 (API 21) wordt elke View gerenderd in zijn eigen hardwareversnellingslaag, waardoor animaties kunnen worden uitgevoerd zonder onDraw aan te roepen.
Extra flexibiliteit in iOS wordt geboden door CAReplicatorLayer en CAEmitterLayer. De eerste wordt gebruikt voor het maken van herhalende patronen, de tweede voor deeltjessystemen. Beide werken uitsluitend op de GPU, waardoor complexe visuele effecten kunnen worden gecreëerd zonder prestatieverlies.
Laaghiërarchie in iOS is opgebouwd volgens het boomprincipe: elke CALayer kan meerdere onderliggende sublayers bevatten. Alle transformaties die op de bovenliggende laag worden toegepast — schaal, rotatie, verschuiving — worden automatisch toegepast op de onderliggende elementen. Dit zorgt voor consistentie van de visuele weergave tijdens animaties.
Scènecompositie wordt uitgevoerd door Core Animation in de volgende volgorde: eerst wordt de achtergrond gerenderd, daarna elke onderliggende laag in de volgorde van toevoegen van onder naar boven. Voor elke laag controleert Core Animation de eigenschappen van transparantie, masks en blending-modi, waarna het samenvoegt (compositing) tot het uiteindelijke frame.
Volgens Apple Documentation wordt compositie van een laag met opaque = true en zonder alfakanaal uitgevoerd zonder extra passes — de GPU kopieert eenvoudigweg pixels over de vorige laag. Als de laag transparantie bevat, voert de GPU alfa-blending uit, wat extra rekenkracht vereist.
In Android wordt laagcompositie uitgevoerd via SurfaceFlinger — de systeemservice die buffers van elke app ontvangt en samenvoegt rekening houdend met de z-volgorde. Elk Window in Android is een aparte Surface die meerdere grafische lagen kan bevatten.
CALayer.mask — de eigenschap waarmee een mask van willekeurige vorm op een laag kan worden toegepast. Het mask kan elke andere CALayer zijn — bijvoorbeeld CAShapeLayer met een cirkelvormig path of CAGradientLayer voor het creëren van een vloeiende transparantieovergang. Het gebruik van masks verhoogt de GPU-belasting omdat het een extra rendering-pass vereist voor het berekenen van alfa-waarden van elke pixel.
Voor eenvoudig bijsnijden langs rechthoekige grenzen wordt aanbevolen cornerRadius en masksToBounds te gebruiken. In tegenstelling tot masks via de mask-eigenschap, wordt cornerRadius hardwarematig verwerkt in de rasterisatiefase en vereist geen extra pass.
shouldRasterize — de belangrijkste CALayer-eigenschap voor prestatieoptimalisatie. Wanneer shouldRasterize op true is ingesteld, rendert Core Animation de laag en al zijn sublayers naar een aparte rasterbuffer (offscreen buffer). Bij volgende frames wordt de gecachte rasterafbeelding gebruikt in plaats van opnieuw renderen.
Caching is effectief voor statische of zelden veranderende lagen: schaduwen, gradiënten, tekst met afgeronde hoeken. Voor vaak bijgewerkte lagen (animatie, video, scrollen) kan rasterisatie de prestaties echter verslechteren, omdat elke frame de cache opnieuw moet genereren.
Volgens onderzoek van Objc.io vermindert correct gebruik van shouldRasterize op iPad Pro de renderingtijd van een complex scherm van 25 ms naar 8 ms — meer dan drie keer. Belangrijke voorwaarde: de laag mag niet vaker dan eens per 3-5 frames veranderen.
Het eerste voorbeeld toont de configuratie van basis visuele eigenschappen van CALayer in Swift — afronden van hoeken, schaduw en rand:
import UIKit
class StyledView: UIView {
override func awakeFromNib() {
super.awakeFromNib()
layer.cornerRadius = 12
layer.masksToBounds = false
layer.shadowColor = UIColor.darkGray.cgColor
layer.shadowOpacity = 0.3
layer.shadowOffset = CGSize(width: 0, height: 4)
layer.shadowRadius = 8
}
}
Het tweede voorbeeld — het maken van een laaganimatie in Swift met CABasicAnimation. De eigenschap position wordt geanimeerd zonder deelname van UIView:
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = NSValue(cgPoint: CGPoint(x: 0, y: 0))
animation.toValue = NSValue(cgPoint: CGPoint(x: 150, y: 300))
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
targetLayer.add(animation, forKey: "moveAnimation")
Het derde voorbeeld — werken met RenderNode in Kotlin op Android. RenderNode — de directe tegenhanger van CALayer, waarmee grafische lagen op Canvas-niveau kunnen worden beheerd:
import android.graphics.renderer.RenderNode
fun createLayer(): RenderNode {
val node = RenderNode("customLayer")
node.setPosition(0, 0, 300, 200)
node.setScaleX(1.5f)
node.setScaleY(1.5f)
val canvas = node.beginRecording()
canvas.drawColor(android.graphics.Color.BLUE)
node.endRecording()
return node
}
Veelgestelde vragen
UIView — is een wrapper rond CALayer die aanraakverwerking en deelname aan Auto Layout toevoegt. Layer houdt zich alleen bezig met rendering en animatie. Direct werken met CALayer is mogelijk, maar voor het verwerken van invoergebeurtenissen is UIView nodig.
shouldRasterize schakelt het cachen van de laag in een aparte offscreen buffer in. Gebruik het voor statische of zelden veranderende elementen met schaduwen of complexe compositie. Gebruik het niet voor vaak geanimeerde lagen — het opnieuw genereren van de cache is duurder dan directe rendering.
Stel de eigenschap cornerRadius in voor het afronden van hoeken en masksToBounds = true voor het bijsnijden van inhoud binnen de laaggrenzen. Voor schaduw moet masksToBounds false zijn, anders wordt de schaduw bijgesneden — gebruik in dat geval een aparte laag voor de schaduw.
Ja, RenderNode in Android 10+ biedt vergelijkbare functionaliteit: beheer van positie, schaal, rotatie en transparantie op het niveau van de grafische laag. Canvas en HardwareRenderer zorgen voor rendering via de GPU. Architectonisch gezien scheidt Android View en laag echter niet zo strikt als iOS.
Schaduw in CALayer wordt berekend via shadowPath of automatisch op basis van het alfakanaal. Automatische berekening vereist het doorlopen van alle pixels van de laag, wat duur is. Specificeer een expliciete shadowPath — een rechthoek of UIBezierPath — dit stelt de GPU in staat de schaduw te berekenen zonder de inhoud te inspecteren.
Samenvatting
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.
Lees ook