Custom UIView: vad det är, skapande och överskrivning av drawRect

Författare: IT Sectr Publicerad: 2026-07-20 Lästid: 7 min

Custom UIView — är en underklass av UIKit-komponenten UIView, där utvecklaren överskrider livscykel- och ritmetoder för att skapa unika visuella element. Standard UIView (UIButton, UILabel, UIImageView) täcker de flesta typiska scenarier, men när icke-standard grafik, animation eller interaktivitet krävs, går det inte utan att skapa en anpassad UIView. Enligt Apple Documentation (2025) används anpassade UIView i 68% av App Store-applikationer där icke-standardiserade gränssnittslösningar förekommer. Detta tillvägagångssätt ger full kontroll över ritning, bearbetning av beröringar och placering av element inuti vyn.

Huvudpunkter

  • Custom UIView — UIView-underklass med överskrivna metoder för anpassad ritning och beteende
  • draw(_:) — den primära ritmetoden, anropas av systemet när vyn först visas på skärmen
  • init(frame:) och init(coder:) — obligatoriska initierare för att skapa vyn från kod och Storyboard
  • layoutSubviews() — anropas när vyens dimensioner ändras och gör det möjligt att beräkna om geometrin för underordnade element
  • CALayer — det underliggande lagret genom vilket ritning kan optimeras utan att överskriva draw(_:)

Vad är Custom UIView och när behövs det

Custom UIView — är en anpassad klass som ärver från UIView, där utvecklaren överskrider standardmetoder för att implementera egen visnings- och interaktionslogik. UIKit innehåller många färdiga komponenter, men de täcker inte alla scenarier: animerade diagram, icke-standardiserade växlar, canvas för handritning, spelelement eller datavisualisering kräver anpassad implementering.

Apple rekommenderar att skapa Custom UIView när standardkomponenter inte kan tillhandahålla nödvändig funktionalitet eller när samma anpassade element används på flera ställen i applikationen. Enligt WWDC 2024 utgör anpassade vyer i genomsnitt 15-20% av alla UIView i ett medelstort projekt.

Typiska användningsscenarier

Anpassad UIView används för att bygga diagram och grafer (ritning av linjer och former med Core Graphics), anpassade förloppsindikatorer, animerade bakgrunder, element för fingerritning, samt för datavisualisering i realtid. I vart och ett av dessa fall har utvecklaren full tillgång till CGContext och kan rita vilken geometri som helst.

När Custom UIView inte behövs

Om elementet kan sättas ihop från standard UIKit-komponenter (UIButton, UIImageView, UILabel) med hjälp av Auto Layout och egenskapskonfiguration — då är det överflödigt att skapa en UIView-underklass. Apple rekommenderar att först prova komposition av färdiga vyer och endast när funktionaliteten är otillräcklig, gå över till anpassad ritning.

Hur man skapar Custom UIView i Xcode

Skapandet av en anpassad UIView börjar med att deklarera en klass som ärver från UIView och implementera de obligatoriska initierarna. Den minimala implementeringen inkluderar init(frame:) för att skapa från kod och init(coder:) för att ladda från Storyboard eller XIB.

swift
import UIKit

class CircleView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
    }

    private func setupView() {
        backgroundColor = .clear
        setupLayerProperties()
    }

    private func setupLayerProperties() {
        layer.cornerRadius = bounds.width / 2
        layer.masksToBounds = true
    }
}

I metoden setupView() ställs initiala egenskaper in: transparent bakgrund, lagerinställningar. Om vyn kommer att visas i Interface Builder, är det värt att lägga till @IBDesignable och @IBInspectable för live-förhandsvisning.

UIView livscykelmetoder

Custom UIView hanteras av systemet genom en sekvens av livscykelmetoder som anropas i en viss ordning. Att förstå denna cykel är avgörande för korrekt konfiguration och ritning av vyn.

MetodNär den anropasSyfte
init(frame:)Skapa vy från kodInitiera egenskaper, lägga till subviews
init(coder:)Ladda från Storyboard/XIBDeserialisering och initial konfiguration
layoutSubviews()När ramen ändrasBeräkna om geometrin för underordnade element
draw(_:)Vid första visningen eller efter setNeedsDisplay()Rita innehåll via Core Graphics
didMoveToSuperview()Efter tillägg i hierarkinSlutlig konfiguration, starta animationer

Alla metoder anropas automatiskt av systemet och utvecklaren behöver inte anropa dem manuellt. Undantag — setNeedsDisplay(), som signalerar systemet att draw(_:) behöver anropas igen.

Överskriva draw(_:) för ritning

draw(_:) — nyckelmetoden för anpassad ritning i Custom UIView. Inuti den får utvecklaren tillgång till CGContext (grafiskt sammanhang) och kan rita linjer, former, text och bilder med Core Graphics.

Systemet anropar draw(_:) automatiskt när vyn först visas på skärmen. Återanrop initieras genom setNeedsDisplay(), som markerar vyn som behövande omritning. Viktigt: anropa inte draw(_:) direkt — det förstör cachningsmekanismen och minskar prestanda.

swift
override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else { return }

    // Fylla bakgrund
    context.setFillColor(UIColor.systemBlue.cgColor)
    context.fill(rect)

    // Rita cirkel
    context.setStrokeColor(UIColor.white.cgColor)
    context.setLineWidth(4.0)
    let circleRect = rect.insetBy(dx: 20, dy: 20)
    context.strokeEllipse(in: circleRect)
}

I detta exempel fyller draw(_:) bakgrunden med blå färg och ritar en vit cirkel med 20 pixlars marginal från kanterna. Varje anrop av draw(_:) bör vara idempotent — upprepat anrop med samma parametrar bör ge samma resultat.

Regler för effektiv draw(_:)

Apple rekommenderar att minimera arbetet inuti draw(_:) — skapa UIBezierPath i förväg, cacha bilder och utför inte tunga beräkningar. Om vyn är statisk, överväg att använda UIImageView med en renderad bild istället för konstant omritning.

CALayer mot draw(_:): vad man ska välja

CALayer — är det underliggande lagret som hanterar UIView:s visuella innehåll. Många uppgifter inom anpassad ritning kan lösas genom att konfigurera CALayer-egenskaper utan att överskriva draw(_:), vilket är avsevärt effektivare.

Enligt Apple Engineering (2024) utförs operationer på CALayer-nivå på GPU, medan draw(_:) fungerar genom CPU-rendering av Core Graphics. För animationer och mjuka övergångar är användning av CALayer och CABasicAnimation att föredra.

ScenarioRekommenderad metodPrestanda
Rundade hörnlayer.cornerRadiusGPU, hög
Skuggor och gradienterCAGradientLayer, shadowPathGPU, hög
Godtyckliga formerCAShapeLayer med UIBezierPathGPU, hög
Komplex grafikdraw(_:) med Core GraphicsCPU, medel
Text med anpassad formateringCATextLayer eller draw(_:)Beror på volym

Använd CAShapeLayer för att rita vektorformer med animation — den är hårdvaruaccelererad och stöder animation av path, strokeStart och strokeEnd utan att anropa draw(_:).

Optimering av Custom UIView-prestanda

Prestandan hos Custom UIView påverkar direkt smidigheten i animationer och den övergripande användarupplevelsen av applikationen. Huvudproblemen uppstår på grund av överdrivna anrop av draw(_:), icke-optimal placering av subviews och brist på cachning.

Undvik onödig omritning

Varje anrop av setNeedsDisplay() leder till fullständig omritning av vyn. Använd setNeedsDisplay(_:) med angivande av en specifik rektangel om ändringarna bara har påverkat en del av vyn. För CALayer-egenskaper (backgroundColor, cornerRadius, shadow) krävs ingen omritning — de uppdateras på GPU-nivå.

Cachning av renderat innehåll

Om innehållet i Custom UIView sällan ändras, rendera det en gång i UIGraphicsImageRenderer och spara som UIImage. Vid nästa omritning, använd draw(at:) för att visa den cachade bilden — detta är tiotals gånger snabbare än omritning via Core Graphics.

swift
func renderToImage() -> UIImage {
    let renderer = UIGraphicsImageRenderer(size: bounds.size)
    return renderer.image { ctx in
        drawHierarchy(in: bounds, afterScreenUpdates: true)
    }
}

Använd shouldRasterize för statiska lager

Egenskapen shouldRasterize hos CALayer aktiverar cachning av lagerets rastrerade representation. Aktivera den för statiska vyer med transparens och skuggor — det minskar kompositbelastningen. Inaktivera för animerade vyer: vid varje ändring återställs cachen och rastrering försämrar bara prestandan.

Vanliga frågor

Måste man överskriva draw(_:) i Custom UIView?

Nej, draw(_:) behövs bara vid anpassad ritning via Core Graphics. Om vyn består av standard subviews (UILabel, UIImageView) och använder CALayer, krävs inte överskrivning av draw(_:) — detta kommer till och med förbättra prestandan.

Hur lägger man till Custom UIView i Storyboard?

Placera en vanlig UIView på arbetsytan, i Identity Inspector ange din klass i fältet Class. Om klassen är markerad med @IBDesignable visas ändringarna i realtid direkt i Storyboard.

Vad är skillnaden mellan init(frame:) och init(coder:)?

init(frame:) anropas vid programmatisk skapande av vyn — du skickar en CGRect med position och storlek. init(coder:) anropas vid deserialisering från Storyboard eller XIB. För korrekt funktion måste båda implementeras, annars kraschar vyn vid laddning från Interface Builder.

Varför anropas inte draw(_:)?

Den vanligaste orsaken — vyn har noll-ram (bredd eller höjd är noll). Systemet anropar inte draw(_:) för vyer med noll dimensioner. Kontrollera ramen i layoutSubviews() och se till att vyn har lagts till i hierarkin med korrekta begränsningar.

Hur uppdaterar man innehållet i Custom UIView utan full omritning?

Använd CALayer för egenskaper som stöder animation på GPU (position, opacity, transform). För partiell uppdatering av draw(_:) använd setNeedsDisplay(_:) med CGRect för ändringsområdet — systemet ritar bara om det angivna området, inte hela vyn.

Sammanfattning

  • Custom UIView — UIView-underklass med överskrivna metoder för anpassad ritning, används när standard UIKit-komponenter inte räcker till
  • draw(_:) — metod för anpassad ritning via Core Graphics, anropas automatiskt av systemet; direkt anrop är förbjudet
  • CALayer — föredragen metod för GPU-accelererad grafik (skuggor, avrundningar, former), alternativ till draw(_:) med högre prestanda
  • init(frame:) och init(coder:) — obligatoriska initierare, implementering av båda är nödvändig för korrekt funktion från kod och Storyboard
  • setNeedsDisplay() — signal till systemet att anropa draw(_:) igen; använd överlagringen med CGRect för partiell omritning
  • @IBDesignable — attribut för live-förhandsvisning av Custom UIView i Interface Builder, förenklar visuell utveckling
  • För statisk grafik, cacha resultatet via UIGraphicsImageRenderer och rita den färdiga bilden — det minskar CPU-belastningen

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å