Custom UIView — je podtřída UIKit komponenty UIView, ve které vývojář přepisuje metody životního cyklu a kreslení pro vytváření jedinečných vizuálních prvků. Standardní UIView (UIButton, UILabel, UIImageView) pokrývají většinu typických scénářů, ale když je vyžadována nestandardní grafika, animace nebo interaktivita, bez vytvoření vlastního UIView se neobejdete. Podle Apple Documentation (2025) se vlastní UIView používají v 68% aplikací v App Store, kde se vyskytují nestandardní řešení rozhraní. Tento přístup poskytuje plnou kontrolu nad kreslením, zpracováním dotyků a rozmístěním prvků uvnitř zobrazení.
Hlavní body
Custom UIView — je vlastní třída dědící z UIView, ve které vývojář přepisuje standardní metody pro implementaci vlastní logiky zobrazení a interakce. UIKit obsahuje mnoho hotových komponent, ale nepokrývají všechny scénáře: animované grafy, nestandardní přepínače, plátno pro kreslení rukou, herní prvky nebo vizualizace dat vyžadují vlastní implementaci.
Apple doporučuje vytvářet Custom UIView, když standardní komponenty nemohou poskytnout potřebnou funkčnost nebo když je stejný vlastní prvek používán na více místech aplikace. Podle WWDC 2024 tvoří vlastní zobrazení v průměru 15-20% všech UIView v projektu střední velikosti.
Vlastní UIView se používá pro vytváření grafů a diagramů (kreslení čar a tvarů pomocí Core Graphics), nestandardních indikátorů průběhu, animovaných pozadí, prvků pro kreslení prstem a pro vizualizaci dat v reálném čase. V každém z těchto případů má vývojář plný přístup k CGContext a může nakreslit libovolnou geometrii.
Pokud lze prvek sestavit ze standardních UIKit komponent (UIButton, UIImageView, UILabel) pomocí Auto Layout a konfigurace vlastností — vytvoření podtřídy UIView bude zbytečné. Apple doporučuje nejprve zkusit kompozici hotových zobrazení a teprve když funkčnost nestačí, přejít k vlastnímu kreslení.
Vytvoření vlastního UIView začíná deklarací třídy dědící z UIView a implementací povinných inicializátorů. Minimální implementace zahrnuje init(frame:) pro vytvoření z kódu a init(coder:) pro načtení ze Storyboard nebo XIB.
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
}
}
V metodě setupView() se nastavují počáteční vlastnosti: průhledné pozadí, nastavení vrstvy. Pokud se bude zobrazení zobrazovat v Interface Builder, stojí za to přidat @IBDesignable a @IBInspectable pro živý náhled.
Custom UIView je spravován systémem prostřednictvím sekvence metod životního cyklu, které jsou volány v určitém pořadí. Pochopení tohoto cyklu je zásadní pro správnou konfiguraci a kreslení zobrazení.
| Metoda | Kdy se volá | Účel |
|---|---|---|
| init(frame:) | Vytvoření view z kódu | Inicializace vlastností, přidání subview |
| init(coder:) | Načtení ze Storyboard/XIB | Deserializace a počáteční konfigurace |
| layoutSubviews() | Při změně rámce | Přepočet geometrie podřízených prvků |
| draw(_:) | Při prvním zobrazení nebo po setNeedsDisplay() | Kreslení obsahu prostřednictvím Core Graphics |
| didMoveToSuperview() | Po přidání do hierarchie | Konečná konfigurace, spuštění animací |
Všechny metody jsou volány automaticky systémem a vývojář je nemusí volat ručně. Výjimkou je setNeedsDisplay(), který signalizuje systému potřebu znovu zavolat draw(_:).
draw(_:) — klíčová metoda pro vlastní kreslení v Custom UIView. Uvnitř ní vývojář získává přístup k CGContext (grafický kontext) a může kreslit čáry, tvary, text a obrázky pomocí Core Graphics.
Systém volá draw(_:) automaticky při prvním zobrazení view na obrazovce. Opětovné volání je iniciováno prostřednictvím setNeedsDisplay(), který označí view jako vyžadující překreslení. Důležité: nevolejte draw(_:) přímo — to narušuje mechanismus ukládání do mezipaměti a snižuje výkon.
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
// Vyplnění pozadí
context.setFillColor(UIColor.systemBlue.cgColor)
context.fill(rect)
// Kreslení kruhu
context.setStrokeColor(UIColor.white.cgColor)
context.setLineWidth(4.0)
let circleRect = rect.insetBy(dx: 20, dy: 20)
context.strokeEllipse(in: circleRect)
}
V tomto příkladu draw(_:) vyplní pozadí modrou barvou a nakreslí bílý kruh s okrajem 20 pixelů od okrajů. Každé volání draw(_:) by mělo být idempotentní — opakované volání se stejnými parametry by mělo dávat stejný výsledek.
Apple doporučuje minimalizovat práci uvnitř draw(_:) — vytvářejte UIBezierPath předem, ukládejte obrázky do mezipaměti a neprovádějte těžké výpočty. Pokud je view statické, zvažte použití UIImageView s vyrenderovaným obrázkem místo neustálého překreslování.
CALayer — je základní vrstva, která spravuje vizuální obsah UIView. Mnoho úkolů vlastního kreslení lze vyřešit konfigurací vlastností CALayer bez přepisování draw(_:), což je výrazně efektivnější.
Podle Apple Engineering (2024) se operace na úrovni CALayer provádějí na GPU, zatímco draw(_:) funguje prostřednictvím CPU renderování Core Graphics. Pro animace a plynulé přechody je preferováno použití CALayer a CABasicAnimation.
| Scénář | Doporučený přístup | Výkon |
|---|---|---|
| Zakulacené rohy | layer.cornerRadius | GPU, vysoký |
| Stíny a gradienty | CAGradientLayer, shadowPath | GPU, vysoký |
| Libovolné tvary | CAShapeLayer s UIBezierPath | GPU, vysoký |
| Složitá grafika | draw(_:) s Core Graphics | CPU, střední |
| Text s vlastním formátováním | CATextLayer nebo draw(_:) | Závisí na objemu |
Používejte CAShapeLayer pro kreslení vektorových tvarů s animací — je hardwarově akcelerovaný a podporuje animaci path, strokeStart a strokeEnd bez volání draw(_:).
Výkon Custom UIView přímo ovlivňuje plynulost animací a celkový dojem z aplikace. Hlavní problémy vznikají kvůli nadměrným voláním draw(_:), neoptimálnímu rozmístění subview a nedostatku ukládání do mezipaměti.
Každé volání setNeedsDisplay() vede k úplnému překreslení view. Používejte setNeedsDisplay(_:) s určením konkrétního obdélníku, pokud změny zasáhly pouze část view. U vlastností CALayer (backgroundColor, cornerRadius, shadow) není překreslení nutné — jsou aktualizovány na úrovni GPU.
Pokud se obsah Custom UIView mění zřídka, vyrenderujte jej jednou v UIGraphicsImageRenderer a uložte jako UIImage. Při dalším překreslení použijte draw(at:) pro zobrazení obrázku z mezipaměti — to je desítkykrát rychlejší než opakované kreslení přes Core Graphics.
func renderToImage() -> UIImage {
let renderer = UIGraphicsImageRenderer(size: bounds.size)
return renderer.image { ctx in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
Vlastnost shouldRasterize u CALayer zapíná ukládání rastrové reprezentace vrstvy do mezipaměti. Zapněte ji pro statická zobrazení s průhledností a stíny — snižuje zátěž kompozitingu. Vypněte ji pro animovaná zobrazení: při každé změně se mezipaměť resetuje a rasterizace pouze zhoršuje výkon.
Často kladené otázky
Ne, draw(_:) je potřeba pouze při vlastním kreslení přes Core Graphics. Pokud se view skládá ze standardních subview (UILabel, UIImageView) a používá CALayer, přepisování draw(_:) není vyžadováno — to dokonce zlepší výkon.
Umístěte běžný UIView na plátno, v Identity Inspector uveďte svou třídu v poli Class. Pokud je třída označena @IBDesignable, změny se budou zobrazovat v reálném čase přímo ve Storyboard.
init(frame:) se volá při programovém vytváření view — předáváte CGRect s pozicí a velikostí. init(coder:) se volá při deserializaci ze Storyboard nebo XIB. Pro správnou funkci musí být implementovány oba, jinak view spadne při načítání z Interface Builder.
Nejčastější příčina — view má nulový rámec (šířka nebo výška je nula). Systém nevolá draw(_:) pro view s nulovými rozměry. Zkontrolujte rámec v layoutSubviews() a ujistěte se, že view bylo přidáno do hierarchie se správnými omezeními.
Používejte CALayer pro vlastnosti podporující animaci na GPU (position, opacity, transform). Pro částečnou aktualizaci draw(_:) použijte setNeedsDisplay(_:) s CGRect oblasti změny — systém překreslí pouze uvedenou oblast, nikoli celé view.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také