Aangepaste weergaven vormen de basis van de unieke interface van elke mobiele app. Aangepaste weergaven in mobiele apps stellen u in staat om uw eigen grafische afbeeldingen, animaties en elementen te maken die niet beschikbaar zijn in standaardcomponenten. Volgens Apple Developer, 2025 blijft drawRect de primaire methode voor aangepast tekenen in mobiele iOS-ontwikkeling. Op Android vervult onDraw met Canvas dezelfde rol, en in Flutter — CustomPainter.
Belangrijkste punten
Aangepaste weergaven zijn door de gebruiker gedefinieerde interfacecomponenten die de standaard teken- en meetmethoden overschrijven om unieke grafische afbeeldingen te maken. Grafieken, animaties, diagrammen, aangepaste chat-elementen en AR-maskers — dit zijn typische gebruiksscenario's voor aangepaste weergaven in mobiele apps. Standaard UI-componenten (Button, TextView, Label) dekken 80% van de taken, maar de resterende 20% vereist volledige controle over het tekenen in mobiele ontwikkeling. Tekenen in mobiele ontwikkeling is een vaardigheid die een junior-ontwikkelaar onderscheidt van een senior.
Aangepaste weergaven in mobiele apps zijn nodig voor unieke 2D-grafische afbeeldingen, complexe animaties, grafieken en datavisualisatie. Als de standaard UIKit het vereiste element niet biedt — wordt een aangepaste weergave gemaakt. In mobiele apps worden aangepaste weergaven gebruikt voor voortgangsbalken, aangepaste knoppen, verlooptinten, geanimeerde pictogrammen en tekenvlakken voor vingertekenen. Het is belangrijk om niet te overdrijven — voor eenvoudige stijlen volstaat het om standaardcomponenten te configureren via de Appearance API.
Op iOS worden aangepaste weergaven gemaakt door overerving van UIView en het overschrijven van de drawRect-methode. drawRect wordt aangeroepen bij de eerste weergave en na elke setNeedsDisplay()-aanroep. Binnen drawRect krijgt de ontwikkelaar een CGContext via UIGraphicsGetCurrentContext() — een canvas voor lijnen, vormen, verlopen en tekst. Core Graphics (Quartz 2D) is een laag-niveau CPU-gebaseerde rendering-engine die volledige controle over elke pixel biedt. UIBezierPath is een handige wrapper voor het maken van paden met beknopte syntaxis.
class CircleView: UIView {
private var fillColor: UIColor = .systemBlue
override func drawRect(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.setFillColor(fillColor.cgColor)
ctx.addEllipse(in: bounds.insetBy(dx: 4, dy: 4))
ctx.drawPath(using: .fill)
}
func updateColor(_ newColor: UIColor) {
fillColor = newColor
setNeedsDisplay()
}
}
Core Graphics biedt CGContext — een canvas voor alle tekenbewerkingen. CGGradient maakt lineaire en radiale verlopen met ondersteuning voor CGColorSpace (sRGB, Display P3). Transformaties worden uitgevoerd via CGAffineTransform — een 3x3-matrix voor rotatie, schaling en translatie. CGContextTranslateCTM, CGContextRotateCTM en CGContextScaleCTM wijzigen het coördinatensysteem. Core Graphics werkt op de CPU, dus complexe grafische afbeeldingen kunnen de processor belasten — gebruik Metal voor GPU-versnelling.
UIBezierPath is een objectgeoriënteerde wrapper over CGPath. De methode addArc(withCenter:radius:startAngle:endAngle:clockwise:) maakt bogen en cirkels, addCurve maakt Bézier-curven. Paden ondersteunen union-, intersection- en subtraction-bewerkingen via addClip. UIBezierPath is handig voor aangepaste maskers (maskView), uitsnijpaden en complexe vormen — sterren, harten, aangepaste pictogrammen.
Op Android breidt een aangepaste weergave View uit met overschreven onDraw(Canvas). Canvas bevat alle tekenmethoden in mobiele ontwikkeling: drawCircle, drawRect, drawLine, drawText, drawBitmap, drawPath en drawRoundRect. Paint configureert parameters — kleur, lijndikte, stijl (FILL, STROKE, FILL_AND_STROKE), anti-aliasing (isAntiAlias) en tekstgrootte. onDraw wordt bij elke invalidate() aangeroepen en mag geen zware bewerkingen bevatten — alle berekeningen worden in de cache opgeslagen.
class CustomCircleView(context: Context, attrs: AttributeSet?)
: View(context, attrs) {
private val paint = Paint().apply {
style = Paint.Style.FILL
color = Color.BLUE
isAntiAlias = true
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val cx = width / 2f
val cy = height / 2f
val radius = minOf(cx, cy) - 4f
canvas.drawCircle(cx, cy, radius, paint)
}
}
Path op Android is het equivalent van UIBezierPath: addCircle, addRect, addOval, lineTo, cubicTo en quadTo. PathMeasure berekent de padlengte en coördinaten op elk punt — nuttig voor het animeren van objectbeweging langs een pad. Voor animaties wordt ValueAnimator gebruikt met invalidate() in de callback. De animator kan kleur, straal, positie wijzigen — elke eigenschap die het tekenen beïnvloedt. Aangepaste weergaven op Android ondersteunen ook StateListDrawable en animated-vector voor animatie via XML.
Verlopen op Android worden ingesteld via Shader — LinearGradient, RadialGradient en SweepGradient. Shader wordt aan Paint toegewezen via paint.setShader(shader). LinearGradient genereert een lineair verloop tussen twee punten met optionele kleurposities. RadialGradient — radiaal van het midden naar de randen. SweepGradient — conisch rond een centraal punt. Shader.TileMode (CLAMP, REPEAT, MIRROR) bepaalt het gedrag buiten de grenzen van het gebied.
Flutter gebruikt CustomPainter — een klasse met de methoden paint(Canvas canvas, Size size) en shouldRepaint. Canvas in Flutter biedt dezelfde methoden als in Android: drawCircle, drawRect, drawLine, drawPath, drawParagraph en drawImage. Paint in Flutter configureert kleur, dikte, stijl en anti-aliasing. Flutter gebruikt geen drawRect of onDraw — al het tekenen gaat via CustomPainter, ingebed in de CustomPaint-widget.
class CirclePainter extends CustomPainter {
final Color color;
CirclePainter({required this.color});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..style = PaintingStyle.fill
..isAntiAlias = true;
final radius = size.shortestSide / 2 - 4;
canvas.drawCircle(size.center(Offset.zero), radius, paint);
}
@override
bool shouldRepaint(CirclePainter oldDelegate) =>
oldDelegate.color != color;
}
shouldRepaint bepaalt of de CustomPainter opnieuw moet worden getekend. Geef alleen true terug wanneer gegevens die de weergave beïnvloeden veranderen — kleur, grootte, grafiekgegevens. RepaintBoundary isoleert het opnieuw tekenen in een aparte laag — gebruik voor widgets die zelden veranderen. Flutter heeft geen setNeedsDisplay of invalidate — opnieuw tekenen wordt geactiveerd via setState of ValueNotifier met het luisteren naar wijzigingen.
Flutter ondersteunt LinearGradient, RadialGradient en SweepGradient — dezelfde typen als in Android. Gradient maakt een Shader voor Paint via createShader(Rect bounds). Transformaties worden uitgevoerd via canvas.rotate, canvas.scale, canvas.translate en canvas.skew. Flutter gebruikt een 4x4-transformatiematrix (Matrix4) voor de Transform-widget. Tekenanimaties in Flutter worden gemaakt met AnimationController in combinatie met setState om CustomPainter opnieuw te tekenen.
Correct meten van aangepaste weergaven is de basis van voorspelbaar interfacegedrag. Op iOS wordt de grootte van de Weergave bepaald via sizeThatFits en intrinsicContentSize. sizeThatFits geeft de optimale grootte terug voor gegeven beperkingen. intrinsicContentSize — de natuurlijke grootte van de inhoud zonder externe beperkingen. Op Android wordt meting geïmplementeerd in onMeasure met MeasureSpec-parameters (UNSPECIFIED, EXACTLY, AT_MOST). In Flutter wordt de grootte doorgegeven aan paint(Canvas, Size) en kan worden berekend via computeDryLayout of LayoutBuilder.
intrinsicContentSize geeft een CGSize terug — de natuurlijke grootte van de Weergave op basis van de inhoud. setContentHuggingPriority en setContentCompressionResistancePriority beheren het gedrag tijdens uitrekken en samendrukken. sizeThatFits wordt door het systeem aangeroepen om de grootte in Auto Layout te berekenen. Voor aangepaste weergaven, overschrijf intrinsicContentSize als uw component een natuurlijke grootte heeft — bijvoorbeeld, een cirkel moet altijd 100x100 zijn.
onMeasure accepteert widthMeasureSpec en heightMeasureSpec. MeasureSpec bevat modus en grootte: UNSPECIFIED (geen beperkingen, Weergave kiest eigen grootte), EXACTLY (exacte grootte van ouder), AT_MOST (maximale grootte). setMeasuredDimension(width, height) slaat het meetresultaat op. Wanneer gegevens veranderen, roep requestLayout() aan voor hermeting. Geneste ViewGroups vereisen het overschrijven van onLayout voor het rangschikken van onderliggende elementen.
| Platform | Meetmethode | Aanroep bij wijziging | Retour |
|---|---|---|---|
| iOS | sizeThatFits / intrinsicContentSize | setNeedsLayout / invalidateIntrinsicContentSize | CGSize |
| Android | onMeasure / setMeasuredDimension | requestLayout / invalidate | void (slaat grootte op) |
| Flutter | computeDryLayout | setState / LayoutBuilder | Size |
computeDryLayout is een RenderObject-methode voor het berekenen van de grootte zonder een volledige layoutcyclus. LayoutBuilder.getSize — een alternatief voor het verkrijgen van beschikbare ruimte in de build-methode. In Flutter wordt de canvasgrootte als Size doorgegeven aan paint en vereist geen afzonderlijke meting — CustomPainter tekent binnen de doorgegeven grenzen. Voor aangepaste RenderObjects moet u echter performLayout en computeDryLayout overschrijven.
Veelgestelde vragen
drawRect is een UIView-methode voor aangepast tekenen via Core Graphics. Het wordt aangeroepen bij de eerste weergave van de Weergave en na elke setNeedsDisplay()-aanroep. Gebruik CGContext binnen drawRect voor lijnen, vormen en tekst.
Maak een klasse die View uitbreidt, overschrijf onDraw(Canvas canvas) en gebruik de Canvas API: drawCircle, drawRect, drawPath. Paint configureert kleur, dikte en stijl. Roep invalidate() aan om bij te werken.
CustomPainter is een Flutter-klasse voor aangepast tekenen op Canvas. Implementeer de methoden paint(Canvas, Size) en shouldRepaint. Het wordt geplaatst via de CustomPaint-widget. Flutter heeft geen drawRect — al het tekenen gaat via CustomPainter.
Op iOS gebruik sizeThatFits en intrinsicContentSize. Op Android — onMeasure met MeasureSpec. In Flutter wordt de grootte doorgegeven aan paint(Canvas, Size) of berekend via computeDryLayout. Elk platform gebruikt zijn eigen meetmethode.
Aangepaste weergaven zijn nodig voor unieke grafische afbeeldingen, animaties, grafieken en elementen die niet kunnen worden geïmplementeerd met standaard UIKit of View. Voor eenvoudige stijlen volstaat het om standaardcomponenten te configureren — maak de architectuur niet onnodig ingewikkeld.
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.