Custom UIView: mi ez, létrehozás és a drawRect felülbírálása

Szerző: IT Sectr Megjelenés: 2026-07-20 Olvasási idő: 7 perc

Custom UIView — az UIKit UIView komponensének egy alosztálya, amelyben a fejlesztő felülírja az életciklus- és rajzolási metódusokat egyedi vizuális elemek létrehozásához. A szabványos UIView-ek (UIButton, UILabel, UIImageView) a legtöbb tipikus forgatókönyvet lefedik, de amikor nem szabványos grafikára, animációra vagy interaktivitásra van szükség, nem lehet megkerülni az egyedi UIView létrehozását. Az Apple Documentation (2025) szerint az egyedi UIView-ek az App Store alkalmazások 68%-ában használatosak, ahol nem szabványos interfész megoldások fordulnak elő. Ez a megközelítés teljes kontrollt biztosít a rajzolás, az érintéskezelés és az elemek elrendezése felett a nézeten belül.

Főbb pontok

  • Custom UIView — UIView alosztály felülírt metódusokkal egyedi rajzoláshoz és viselkedéshez
  • draw(_:) — a fő rajzolási metódus, amelyet a rendszer a nézet első képernyőn való megjelenésekor hív meg
  • init(frame:) és init(coder:) — kötelező inicializálók a nézet kódból és Storyboard-ból történő létrehozásához
  • layoutSubviews() — a nézet méreteinek változásakor hívódik meg, és lehetővé teszi a gyermek elemek geometriájának újraszámítását
  • CALayer — az alatta lévő réteg, amelyen keresztül a rajzolás optimalizálható a draw(_:) felülírása nélkül

Mi az a Custom UIView és mikor van rá szükség

Custom UIView — egy egyedi osztály, amely a UIView-ből öröklődik, és amelyben a fejlesztő felülírja a szabványos metódusokat saját megjelenítési és interakciós logikájának megvalósításához. Az UIKit számos kész komponenst tartalmaz, de ezek nem fednek le minden forgatókönyvet: animált grafikonok, nem szabványos kapcsolók, kézzel rajzoláshoz használt vászon, játékelemek vagy adatvizualizáció egyedi megvalósítást igényelnek.

Az Apple akkor javasolja a Custom UIView létrehozását, amikor a szabványos komponensek nem tudják biztosítani a szükséges funkcionalitást, vagy amikor ugyanaz az egyedi elem az alkalmazás több helyén is használatos. A WWDC 2024 szerint az egyedi nézetek átlagosan az összes UIView 15-20%-át teszik ki egy közepes méretű projektben.

Tipikus használati forgatókönyvek

Az egyedi UIView grafikonok és diagramok (vonalak és alakzatok rajzolása Core Graphics segítségével), nem szabványos folyamatjelzők, animált hátterek, ujjal rajzoláshoz használt elemek, valamint valós idejű adatvizualizáció építésére használható. Mindegyik esetben a fejlesztő teljes hozzáféréssel rendelkezik a CGContext-hez, és bármilyen geometriát lerajzolhat.

Mikor nincs szükség Custom UIView-ra

Ha az elem összeállítható szabványos UIKit komponensekből (UIButton, UIImageView, UILabel) Auto Layout és tulajdonságok beállításával — akkor a UIView alosztály létrehozása felesleges. Az Apple azt javasolja, hogy először próbálja ki a kész nézetek kompozícióját, és csak akkor térjen át az egyedi rajzolásra, ha a funkcionalitás nem elegendő.

Hogyan hozzunk létre Custom UIView-t Xcode-ban

Az egyedi UIView létrehozása a UIView-ből öröklődő osztály deklarálásával és a kötelező inicializálók megvalósításával kezdődik. A minimális megvalósítás tartalmazza a init(frame:)-et a kódból történő létrehozáshoz és a init(coder:)-t a Storyboard-ból vagy XIB-ből történő betöltéshez.

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
    }
}

A setupView() metódusban a kezdeti tulajdonságok kerülnek beállításra: átlátszó háttér, rétegbeállítások. Ha a nézet megjelenik az Interface Builder-ben, érdemes hozzáadni a @IBDesignable és @IBInspectable attribútumokat az élő előnézethez.

UIView életciklus metódusok

Custom UIView a rendszer által egy meghatározott sorrendben meghívott életciklus metódusok sorozatán keresztül kerül vezérlésre. Ennek a ciklusnak a megértése kritikus fontosságú a nézet helyes konfigurálásához és rajzolásához.

MetódusMikor hívódikCél
init(frame:)Nézet létrehozása kódbólTulajdonságok inicializálása, alnézetek hozzáadása
init(coder:)Betöltés Storyboard/XIB-bőlDeszerializáció és kezdeti konfiguráció
layoutSubviews()A keret megváltozásakorGyermek elemek geometriájának újraszámítása
draw(_:)Első megjelenéskor vagy setNeedsDisplay() utánTartalom rajzolása Core Graphics segítségével
didMoveToSuperview()A hierarchiába való hozzáadás utánVégső konfiguráció, animációk elindítása

Minden metódus automatikusan meghívódik a rendszer által, és a fejlesztőnek nem kell azokat manuálisan meghívnia. Kivétel — a setNeedsDisplay(), amely jelzi a rendszernek a draw(_:) újbóli meghívásának szükségességét.

A draw(_:) felülírása rajzoláshoz

draw(_:) — a kulcsmetódus az egyedi rajzoláshoz a Custom UIView-ben. Belül a fejlesztő hozzáférést kap a CGContext-hez (grafikus környezet), és vonalakat, alakzatokat, szöveget és képeket rajzolhat a Core Graphics segítségével.

A rendszer automatikusan meghívja a draw(_:)-t a nézet első képernyőn való megjelenésekor. Az újbóli meghívást a setNeedsDisplay() kezdeményezi, amely megjelöli a nézetet, mint újrarajzolást igénylőt. Fontos: ne hívja meg közvetlenül a draw(_:)-t — ez tönkreteszi a gyorsítótárazási mechanizmust és csökkenti a teljesítményt.

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

    // Háttér kitöltése
    context.setFillColor(UIColor.systemBlue.cgColor)
    context.fill(rect)

    // Kör rajzolása
    context.setStrokeColor(UIColor.white.cgColor)
    context.setLineWidth(4.0)
    let circleRect = rect.insetBy(dx: 20, dy: 20)
    context.strokeEllipse(in: circleRect)
}

Ebben a példában a draw(_:) kék színnel tölti ki a hátteret és egy fehér kört rajzol 20 pixel margóval a szélektől. Minden draw(_:) hívásnak idempotensnek kell lennie — az azonos paraméterekkel történő ismételt hívásnak ugyanazt az eredményt kell adnia.

Hatékony draw(_:) szabályok

Az Apple a draw(_:) belsejében végzett munka minimalizálását javasolja — hozza létre előre a UIBezierPath-et, gyorsítótárazza a képeket, és ne végezzen nehéz számításokat. Ha a nézet statikus, fontolja meg a UIImageView használatát egy előre renderelt képpel az állandó újrarajzolás helyett.

CALayer kontra draw(_:): melyiket válasszuk

CALayer — az alatta lévő réteg, amely a UIView vizuális tartalmát kezeli. Az egyedi rajzolás számos feladata megoldható a CALayer tulajdonságainak konfigurálásával a draw(_:) felülírása nélkül, ami jelentősen hatékonyabb.

Az Apple Engineering (2024) szerint a CALayer szintű műveletek a GPU-n hajtódnak végre, míg a draw(_:) a CPU Core Graphics renderelésén keresztül működik. Animációkhoz és sima átmenetekhez a CALayer és a CABasicAnimation használata előnyösebb.

ForgatókönyvAjánlott megközelítésTeljesítmény
Lekerekített sarkoklayer.cornerRadiusGPU, magas
Árnyékok és gradiensekCAGradientLayer, shadowPathGPU, magas
Tetszőleges alakzatokCAShapeLayer UIBezierPath-pelGPU, magas
Összetett grafikadraw(_:) Core Graphics-szalCPU, közepes
Szöveg egyedi formázássalCATextLayer vagy draw(_:)Mennyiségtől függ

Használja a CAShapeLayer-t vektoros alakzatok rajzolásához animációval — hardveresen gyorsított, és támogatja a path, strokeStart és strokeEnd animációját a draw(_:) meghívása nélkül.

Custom UIView teljesítmény optimalizálása

A Custom UIView teljesítménye közvetlenül befolyásolja az animációk simaságát és az alkalmazás általános felhasználói élményét. A fő problémák a draw(_:) túlzott meghívásából, az alnézetek nem optimális elrendezéséből és a gyorsítótárazás hiányából adódnak.

Kerülje a szükségtelen újrarajzolásokat

Minden setNeedsDisplay() hívás a nézet teljes újrarajzolásához vezet. Használja a setNeedsDisplay(_:)-t egy adott téglalap megadásával, ha a változtatások csak a nézet egy részét érintik. A CALayer tulajdonságokhoz (backgroundColor, cornerRadius, shadow) nincs szükség újrarajzolásra — ezek GPU szinten frissülnek.

Renderelt tartalom gyorsítótárazása

Ha a Custom UIView tartalma ritkán változik, renderelje le egyszer a UIGraphicsImageRenderer-ben, és mentse el UIImage-ként. A következő újrarajzoláskor használja a draw(at:)-t a gyorsítótárazott kép megjelenítéséhez — ez több tízszer gyorsabb, mint a Core Graphics-on keresztüli újrarajzolás.

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

Használja a shouldRasterize-t statikus rétegekhez

A CALayer shouldRasterize tulajdonsága bekapcsolja a réteg raszteres megjelenítésének gyorsítótárazását. Kapcsolja be statikus nézetekhez átlátszósággal és árnyékokkal — ez csökkenti a kompozitálási terhelést. Kapcsolja ki animált nézetekhez: minden változásnál a gyorsítótár alaphelyzetbe áll, és a raszterizáció csak rontja a teljesítményt.

Gyakran ismételt kérdések

Kötelező felülírni a draw(_:)-t a Custom UIView-ben?

Nem, a draw(_:) csak egyedi rajzoláshoz szükséges a Core Graphics-on keresztül. Ha a nézet szabványos alnézetekből (UILabel, UIImageView) áll és CALayer-t használ, a draw(_:) felülírása nem szükséges — ez még javít is a teljesítményen.

Hogyan adjunk hozzá Custom UIView-t a Storyboard-ban?

Helyezzen egy szokásos UIView-t a vászonra, az Identity Inspector-ban adja meg az osztályát a Class mezőben. Ha az osztály @IBDesignable jelöléssel rendelkezik, a változtatások valós időben, közvetlenül a Storyboard-ban jelennek meg.

Mi a különbség az init(frame:) és az init(coder:) között?

Az init(frame:) a nézet programozott létrehozásakor hívódik — Ön egy CGRect-et ad át pozícióval és mérettel. Az init(coder:) a Storyboard-ból vagy XIB-ből történő deszerializációkor hívódik. A helyes működéshez mindkettőt implementálni kell, különben a nézet összeomlik az Interface Builder-ből való betöltéskor.

Miért nem hívódik meg a draw(_:)?

A leggyakoribb ok — a nézet nulla kerettel rendelkezik (a szélesség vagy a magasság nulla). A rendszer nem hívja meg a draw(_:)-t nulla méretű nézetek esetén. Ellenőrizze a keretet a layoutSubviews()-ban, és győződjön meg arról, hogy a nézet megfelelő korlátokkal lett hozzáadva a hierarchiához.

Hogyan frissíthető a Custom UIView tartalma teljes újrarajzolás nélkül?

Használja a CALayer-t azokhoz a tulajdonságokhoz, amelyek támogatják a GPU-s animációt (position, opacity, transform). A draw(_:) részleges frissítéséhez alkalmazza a setNeedsDisplay(_:)-t a változtatási terület CGRect-jével — a rendszer csak a megadott területet rajzolja újra, nem a teljes nézetet.

Összefoglalás

  • Custom UIView — UIView alosztály felülírt metódusokkal egyedi rajzoláshoz, akkor használatos, amikor a szabványos UIKit komponensek nem elegendőek
  • draw(_:) — metódus egyedi rajzoláshoz a Core Graphics-on keresztül, a rendszer automatikusan hívja; közvetlen hívás tilos
  • CALayer — előnyben részesített módszer GPU-gyorsított grafikához (árnyékok, lekerekítések, alakzatok), alternatíva a draw(_:) helyett magasabb teljesítménnyel
  • init(frame:) és init(coder:) — kötelező inicializálók, mindkettő implementálása szükséges a kódból és Storyboard-ból történő helyes működéshez
  • setNeedsDisplay() — jelzés a rendszernek a draw(_:) újbóli meghívásához; használja a CGRect-es túlterhelést részleges újrarajzoláshoz
  • @IBDesignable — attribútum a Custom UIView élő előnézetéhez az Interface Builder-ben, leegyszerűsíti a vizuális fejlesztést
  • Statikus grafikához gyorsítótárazza az eredményt a UIGraphicsImageRenderer segítségével, és rajzolja ki a kész képet — ez csökkenti a CPU terhelést

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is