UIBezierPath: co to je, metody kreslení a jak funguje

Autor: IT Sectr Publikováno: 2026-07-21 Doba čtení: 8 min

UIBezierPath — třída z UIKit, která zapouzdřuje vektorovou cestu pro 2D grafiku v iOS. Spojuje geometrický popis kontury s možnostmi kreslení a umožňuje vytvářet čáry, Bézierovy křivky, oblouky a obdélníky. Na rozdíl od CGPath obsahuje UIBezierPath vlastní metody kreslení přímo v aktuálním grafickém kontextu. Podle Apple Developer Documentation, 2026 podporuje UIBezierPath všechny standardní operace Quartz 2D v objektově orientovaném obalu.

Hlavní body

  • UIBezierPath — objektově orientovaný obal CGPath pro práci s vektorovými konturami v UIKit.
  • move(to:) a addLine(to:) definují přímé úseky cesty.
  • addQuadCurve(to:controlPoint:) a addCurve(to:controlPoint1:controlPoint2:) vytvářejí Bézierovy křivky.
  • addArc(withCenter:radius:startAngle:endAngle:clockwise:) vytváří oblouky a sektory.
  • fill a stroke — přímé kreslení cesty v aktuálním kontextu bez použití dalších objektů.

Co je UIBezierPath?

UIBezierPath — třída frameworku UIKit, dědící NSObject a implementující NSCopying, NSSecureCoding. Poskytuje vysokoúrovňové Objective-C/Swift API pro stavbu a kreslení vektorových kontur. Interně UIBezierPath ukládá referenci na CGPathRef — objekt Core Graphics, ale přidává pohodlné metody pro kreslení, změnu geometrie a správu stylů.

Hlavní výhoda UIBezierPath oproti přímému použití CGPath jsou vestavěné metody kreslení. Volání fill() nebo stroke() na instanci UIBezierPath automaticky nakonfiguruje kontext a nakreslí cestu. Třída také podporuje vlastnosti lineWidth, lineCapStyle, lineJoinStyle, miterLimit a flatness, což umožňuje spravovat vzhled bez samostatného objektu pro ukládání stylů.

UIBezierPath se používá ve většině iOS aplikací pro vlastní kreslení uvnitř UIView: od jednoduchých ikon po složité animované grafy. Metoda draw(_:) třídy UIView je hlavním místem, kde vývojáři vytvářejí a kreslí UIBezierPath. Třída je plně kompatibilní s Core Animation a lze ji použít pro animaci cesty přes CAShapeLayer a CABasicAnimation.

Přímé čáry a obdélníky

Metoda move(to:) přesune počáteční bod cesty na zadané souřadnice bez kreslení. Toto je povinné volání před stavbou libovolného segmentu. addLine(to:) přidá přímý úsek z aktuální pozice do zadaného bodu. Pro uzavření kontury se používá metoda close(), která vede čáru od posledního bodu k prvnímu bodu posledního move(to:).

Obdélníky se zaoblenými rohy

UIBezierPath poskytuje několik pohodlných inicializátorů pro hotové tvary. init(rect:) vytvoří obdélník, init(roundedRect:cornerRadius:) — obdélník se zaoblenými rohy. Parametr UIRectCorner umožňuje zaoblovat pouze vybrané rohy, například topLeft a bottomRight, ostatní nechává rovné. To je široce používáno pro vytváření vlastních tlačítek a karet.

init(ovalIn:) vytvoří elipsu vepsanou do zadaného obdélníku. Pokud je obdélník čtverec, elipsa se změní na kruh. init(roundedRect:byRoundingCorners:cornerRadii:) — nejflexibilnější varianta, umožňující nastavit různé poloměry pro každý roh. Tento inicializátor se objevil v iOS 6 a zůstává standardem pro vytváření zaoblených kontejnerů.

swift
let path = UIBezierPath()
path.move(to: CGPoint(x: 50, y: 50))
path.addLine(to: CGPoint(x: 200, y: 50))
path.addLine(to: CGPoint(x: 200, y: 150))
path.addLine(to: CGPoint(x: 125, y: 200))
path.addLine(to: CGPoint(x: 50, y: 150))
path.close()

Bézierovy křivky: kvadratické a kubické

addQuadCurve(to:controlPoint:) přidá kvadratickou Bézierovu křivku s jedním řídicím bodem. Tento typ křivky se používá pro jednoduché plynulé ohyby, když je třeba minimalizovat počet výpočtů. Kvadratická křivka je vždy parabola a zaručeně leží uvnitř trojúhelníku tvořeného počátečním, řídicím a koncovým bodem.

Kubické Bézierovy křivky

addCurve(to:controlPoint1:controlPoint2:) přidá kubickou Bézierovu křivku se dvěma řídicími body. Kubické křivky se používají ve všech moderních vektorových editorech a TrueType fontech. Dva řídicí body poskytují více stupňů volnosti pro přesné řízení tvaru křivky. Tato metoda je doporučena pro stavbu organických a složitých kontur.

Při stavbě křivek je důležité dodržovat princip spojitosti — hladkost křivky v bodě připojení segmentů. Pro spojitost C1 (tečna) musí řídicí bod následující křivky ležet na stejné přímce jako řídicí bod předchozí. Pro spojitost C2 (křivost) je vyžadováno složitější přizpůsobení, které je automaticky zajištěno v CAShapeLayer při animaci mezi dvěma UIBezierPath se stejným počtem řídicích bodů.

MetodaTypŘídicích bodůStupeň
addQuadCurveKvadratická Bézier12
addCurveKubická Bézier23
addArcOblouk

Oblouky a kruhy

addArc(withCenter:radius:startAngle:endAngle:clockwise:) přidá oblouk kruhu se zadanými parametry. Úhly se zadávají v radiánech vzhledem ke středu kruhu. Nulový úhel odpovídá směru doprava (3 hodiny na ciferníku). Parametr clockwise určuje směr: true — po směru hodinových ručiček, false — proti směru. Oblouky jsou nepostradatelné pro koláčové grafy, rychloměry a interaktivní prstence průběhu.

Kruhy a sektory

Pro plný kruh stačí startAngle = 0 a endAngle = .pi * 2. Pro vytvoření sektoru (jako část koláčového grafu) použijte addArc následovaný addLine(to:) do středu a close(). UIBezierPath nemá vestavěnou metodu addCircle — kruh se vytvoří přes init(ovalIn:) se čtvercovým obdélníkem nebo přes addArc s plným úhlem.

Metoda addArc(withCenter:radius:startAngle:endAngle:clockwise:) automaticky provede move(to:) do počátečního bodu oblouku, pokud se aktuální pozice s ním neshoduje. Pokud je aktuální pozice jiná, je mezi ní a začátkem oblouku vedena přímá čára. Toto chování se liší od práce s Core Graphics, kde je vyžadován explicitní move(to:) před každou novou konturou.

swift
let center = CGPoint(x: 150, y: 150)
let slice = UIBezierPath()
slice.move(to: center)
slice.addArc(
    withCenter: center,
    radius: 100,
    startAngle: 0,
    endAngle: .pi * 0.75,
    clockwise: true
)
slice.close()

Vyplnění a obrys cesty

fill() vyplní vnitřní oblast cesty aktuální barvou fillColor nebo barvou nastavenou v grafickém kontextu přes setFill(). Pro cesty s vlastními průsečíky je pravidlo vyplnění určeno vlastností usesEvenOddFillRule. Pokud je true, použije se pravidlo even-odd: bod je považován za uvnitř tvaru, pokud paprsek z něj protíná konturu lichý počet krát.

Konfigurace obrysu

stroke() kreslí konturu cesty s aktuálním nastavením lineWidth, lineCapStyle a lineJoinStyle. lineCapStyle určuje tvar konců otevřených segmentů: .butt (rovný řez), .round (půlkruhový), .square (čtvercový s výstupkem). lineJoinStyle určuje tvar rohů spojů: .miter (ostrý), .round (zaoblený), .bevel (seříznutý).

Pro přerušované čáry se používá vlastnost setLineDash(_:count:phase:). Přijímá pole délek střídajících se čárek a mezer, počet prvků a počáteční fázi. Vizualizace přerušované čáry probíhá ve fázi rasterizace cesty — složité vzory nezvyšují geometrickou složitost kontury. CAShapeLayer podporuje animaci vlastnosti strokeEnd pro efekt “kreslení” čáry od začátku do konce.

swift
override func draw(_ rect: CGRect) {
    let path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 200, height: 200))
    UIColor.blue.setFill()
    UIColor.black.setStroke()
    path.lineWidth = 4
    path.fill()
    path.stroke()
}

Příklad vytvoření složitého tvaru

Vytvořme vlastní indikátor průběhu ve tvaru prstence pomocí UIBezierPath. Prstenec se staví ze dvou oblouků stejného poloměru, ale s různou barvou obrysu. První oblouk je plný šedý kruh (pozadí), druhý je segment zobrazující průběh. Pro animaci se používají CAShapeLayer a CABasicAnimation.

swift
class RingView: UIView {

    private let progressLayer = CAShapeLayer()

    override func layoutSubviews() {
        super.layoutSubviews()
        let center = CGPoint(x: bounds.midX, y: bounds.midY)
        let radius = bounds.width * 0.4
        let lineWidth: CGFloat = 12

        let backgroundRing = UIBezierPath()
        backgroundRing.addArc(withCenter: center, radius: radius,
                          startAngle: -.pi / 2, endAngle: .pi * 1.5, clockwise: true)

        progressLayer.path = backgroundRing.cgPath
        progressLayer.strokeColor = UIColor.systemBlue.cgColor
        progressLayer.lineWidth = lineWidth
        progressLayer.lineCap = .round
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.strokeEnd = 0
        layer.addSublayer(progressLayer)
    }

    func animateProgress(to value: CGFloat) {
        CABasicAnimation(keyPath: "strokeEnd").apply {
            $0.toValue = value
            $0.duration = 1.5
            $0.timingFunction = CAMediaTimingFunction(name: .easeOut)
            progressLayer.add($0, forKey: nil)
        }
        progressLayer.strokeEnd = value
    }
}

V tomto příkladu se UIBezierPath používá k vytvoření kruhové kontury, která je pak předána CAShapeLayer přes vlastnost cgPath. Animace strokeEnd od 0 do 1 vizualizuje vyplňování prstence. Tento přístup se používá v indikátorech načítání, fitness trackerech a widgetech průběhu. Metoda layoutSubviews zaručuje přestavbu cesty při změně rozměrů View.

lineCap = .round přidá zaoblené konce oblouku, což dává indikátoru úhlednější vzhled. Vlastnost strokeEnd je animovatelná vlastnost CAShapeLayer, která nevyžaduje překreslení celé kontury v každém snímku. Animace je provedena zcela na GPU přes Core Animation, což zajišťuje 60 FPS bez zatížení CPU.

Často kladené otázky

Čím se liší UIBezierPath od CGPath?

UIBezierPath — objektově orientovaný obal CGPath obsahující vestavěné metody fill() a stroke(). CGPath je nemodifikovatelný C objekt Core Graphics vyžadující explicitní kreslení přes CGContext. UIBezierPath je pohodlnější pro UIKit, CGPath je výkonnější pro opakované použití.

Jak zaoblit pouze horní rohy obdélníku?

Použijte init(roundedRect:byRoundingCorners:cornerRadii:) s parametrem .topLeft a .topRight pro roundedRect. Toto je jediná metoda UIBezierPath umožňující selektivní zaoblení rohů bez vytváření složité složené cesty.

Jak znovu použít UIBezierPath s různými styly?

Vlastnost cgPath vrací neměnný CGPathRef, který lze předat CAShapeLayer nebo použít s různými barvami a tloušťkami. Modifikace UIBezierPath (přesun bodů) neovlivní dříve získaný cgPath do explicitní aktualizace.

Proč fill() nevyplňuje celou cestu?

Zkontrolujte usesEvenOddFillRule — pokud má kontura vlastní průsečíky, pravidlo even-odd může ponechat oblasti nevyplněné. Nastavte usesEvenOddFillRule = false pro standardní pravidlo vyplnění non-zero winding.

Jak animovat tvar UIBezierPath?

Použijte CABasicAnimation s klíčovou cestou “path” na CAShapeLayer. Oba stavy cesty musí obsahovat stejný počet segmentů a řídicích bodů — jinak bude animace trhaná nebo nebude fungovat.

Shrnutí

  • UIBezierPath — objektově orientovaná třída UIKit pro práci s vektorovými konturami a 2D grafikou.
  • move(to:) a addLine(to:) — základní metody stavby přímých čar a mnohoúhelníků.
  • addQuadCurve a addCurve vytvářejí kvadratické a kubické Bézierovy křivky s jedním a dvěma řídicími body.
  • addArc kreslí oblouky kruhu s flexibilním řízením úhlů a směru.
  • fill() a stroke() provádějí kreslení přímo v aktuálním grafickém kontextu.
  • Inicializátory init(roundedRect:) a init(ovalIn:) urychlují vytváření standardních tvarů.
  • Vlastnost cgPath umožňuje integraci UIBezierPath s Core Animation a CAShapeLayer pro animaci.

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í.

Prodiskutovat projekt

Přečtěte si také