UIBezierPath: ce este, metode de desenare și cum funcționează

Autor: IT Sectr Publicat: 2026-07-21 Timp de citire: 8 min

UIBezierPath — o clasă din UIKit care încapsulează o cale vectorială pentru grafica 2D în iOS. Combină descrierea geometrică a conturului cu capacitățile de desenare, permițând crearea de linii, curbe Bézier, arcuri și dreptunghiuri. Spre deosebire de CGPath, UIBezierPath conține metode proprii de desenare direct în contextul grafic curent. Conform Apple Developer Documentation, 2026, UIBezierPath suportă toate operațiile standard Quartz 2D într-o îmbrăcăminte orientată pe obiecte.

Principalele puncte

  • UIBezierPath — îmbrăcămintea orientată pe obiecte a CGPath pentru lucrul cu contururi vectoriale în UIKit.
  • move(to:) și addLine(to:) definesc segmente drepte ale căii.
  • addQuadCurve(to:controlPoint:) și addCurve(to:controlPoint1:controlPoint2:) construiesc curbe Bézier.
  • addArc(withCenter:radius:startAngle:endAngle:clockwise:) creează arcuri și sectoare.
  • fill și stroke — desenarea directă a căii în contextul curent fără a utiliza obiecte suplimentare.

Ce este UIBezierPath?

UIBezierPath — o clasă a framework-ului UIKit, moștenind NSObject și implementând NSCopying, NSSecureCoding. Oferă un API de nivel înalt Objective-C/Swift pentru construirea și desenarea contururilor vectoriale. Intern, UIBezierPath stochează o referință la CGPathRef — un obiect Core Graphics, dar adaugă metode convenabile pentru desenare, modificarea geometriei și gestionarea stilurilor.

Principalul avantaj al UIBezierPath față de utilizarea directă a CGPath sunt metodele de desenare încorporate. Apelarea fill() sau stroke() pe o instanță UIBezierPath configurează automat contextul și desenează calea. Clasa suportă și proprietățile lineWidth, lineCapStyle, lineJoinStyle, miterLimit și flatness, permițând gestionarea aspectului fără un obiect separat pentru stocarea stilurilor.

UIBezierPath este folosit în majoritatea aplicațiilor iOS pentru desenarea personalizată în interiorul UIView: de la pictograme simple la grafice animate complexe. Metoda draw(_:) a clasei UIView este locul principal unde dezvoltatorii creează și desenează UIBezierPath. Clasa este complet compatibilă cu Core Animation și poate fi folosită pentru animarea căii prin CAShapeLayer și CABasicAnimation.

Linii drepte și dreptunghiuri

Metoda move(to:) mută punctul de pornire al căii la coordonatele date fără a desena. Aceasta este o apelare obligatorie înainte de construirea oricărui segment. addLine(to:) adaugă un segment drept de la poziția curentă la punctul specificat. Pentru închiderea conturului se folosește metoda close(), care trasează o linie de la ultimul punct la primul punct al ultimului move(to:).

Dreptunghiuri cu colțuri rotunjite

UIBezierPath oferă mai mulți inițializatori convenabili pentru figuri gata făcute. init(rect:) creează un dreptunghi, init(roundedRect:cornerRadius:) — un dreptunghi cu colțuri rotunjite. Parametrul UIRectCorner permite rotunjirea doar a colțurilor selectate, de exemplu topLeft și bottomRight, lăsându-le pe celelalte drepte. Acest lucru este utilizat pe scară largă pentru crearea de butoane și carduri personalizate.

init(ovalIn:) creează o elipsă înscrisă în dreptunghiul dat. Dacă dreptunghiul este un pătrat, elipsa se transformă într-un cerc. init(roundedRect:byRoundingCorners:cornerRadii:) — cea mai flexibilă variantă, permițând setarea unor raze diferite pentru fiecare colț. Acest inițializator a apărut în iOS 6 și rămâne standardul pentru crearea containerelor rotunjite.

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()

Curbe Bézier: pătratice și cubice

addQuadCurve(to:controlPoint:) adaugă o curbă Bézier pătratică cu un punct de control. Acest tip de curbă este folosit pentru îndoiri line simple, când se dorește minimizarea numărului de calcule. Curba pătratică este întotdeauna o parabolă și se află garantat în interiorul triunghiului format de punctele de pornire, control și final.

Curbe Bézier cubice

addCurve(to:controlPoint1:controlPoint2:) adaugă o curbă Bézier cubică cu două puncte de control. Curbele cubice sunt utilizate în toate editoarele vectoriale moderne și fonturile TrueType. Două puncte de control oferă mai multe grade de libertate pentru controlul precis al formei curbei. Această metodă este recomandată pentru construirea contururilor organice și complexe.

La construirea curbelor este important să se respecte principiul continuității — netezimea curbei în punctul de îmbinare a segmentelor. Pentru continuitatea C1 (tangentă), punctul de control al curbei următoare trebuie să se afle pe aceeași linie dreaptă cu punctul de control al precedentei. Pentru continuitatea C2 (curbură) este necesară o ajustare mai complexă, care este asigurată automat în CAShapeLayer la animația între două UIBezierPath cu același număr de puncte de control.

MetodăTipPuncte de controlGrad
addQuadCurveBézier pătratică12
addCurveBézier cubică23
addArcArc

Arcuri și cercuri

addArc(withCenter:radius:startAngle:endAngle:clockwise:) adaugă un arc de cerc cu parametrii dați. Unghiurile sunt specificate în radiani față de centrul cercului. Unghiul zero corespunde direcției spre dreapta (ora 3 pe cadran). Parametrul clockwise determină direcția: true — în sensul acelor de ceas, false — invers. Arcurile sunt indispensabile pentru diagrame circulare, vitezometre și inele interactive de progres.

Cercuri și sectoare

Pentru un cerc complet sunt suficiente startAngle = 0 și endAngle = .pi * 2. Pentru crearea unui sector (ca parte a unei diagrame circulare) utilizați addArc urmat de addLine(to:) la centru și close(). UIBezierPath nu are o metodă încorporată addCircle — cercul se creează prin init(ovalIn:) cu un dreptunghi pătrat sau prin addArc cu unghi complet.

Metoda addArc(withCenter:radius:startAngle:endAngle:clockwise:) execută automat move(to:) la punctul de pornire al arcului dacă poziția curentă nu coincide cu acesta. Dacă poziția curentă este diferită, între ea și începutul arcului se trasează o linie dreaptă. Acest comportament diferă de lucrul cu Core Graphics, unde este necesar un move(to:) explicit înainte de fiecare nou contur.

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()

Umplerea și conturarea căii

fill() umple zona interioară a căii cu culoarea curentă fillColor sau culoarea setată în contextul grafic prin setFill(). Pentru căi cu auto-intersectări, regula de umplere este determinată de proprietatea usesEvenOddFillRule. Dacă este true, se aplică regula even-odd: un punct este considerat în interiorul figurii dacă raza din el intersectează conturul de un număr impar de ori.

Configurarea conturului

stroke() desenează conturul căii cu setările curente lineWidth, lineCapStyle și lineJoinStyle. lineCapStyle determină forma capetelor segmentelor deschise: .butt (tăietură dreaptă), .round (semi-circular), .square (pătrat cu proeminență). lineJoinStyle specifică forma colțurilor îmbinărilor: .miter (ascuțit), .round (rotunjit), .bevel (tăiat).

Pentru linii întrerupte se utilizează proprietatea setLineDash(_:count:phase:). Aceasta primește un tablou de lungimi alternante de linii și spații, numărul de elemente și faza inițială. Vizualizarea liniei întrerupte are loc în etapa de rasterizare a căii — modelele complexe nu cresc complexitatea geometrică a conturului. CAShapeLayer suportă animația proprietății strokeEnd pentru efectul de „desenare“ a liniei de la început la sfârșit.

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

Exemplu de creare a unei figuri complexe

Să creăm un indicator de progres personalizat sub formă de inel folosind UIBezierPath. Inelul se construiește din două arcuri de aceeași rază, dar cu culoare diferită a conturului. Primul arc — un cerc complet de culoare gri (fundal), al doilea — segmentul care arată progresul. Pentru animație se folosesc CAShapeLayer și 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
    }
}

În acest exemplu UIBezierPath este folosit pentru a crea un contur circular, care apoi este transmis către CAShapeLayer prin proprietatea cgPath. Animația strokeEnd de la 0 la 1 vizualizează umplerea inelului. Această abordare este folosită în indicatorii de încărcare, trackerele de fitness și widgeturile de progres. Metoda layoutSubviews garantează reconstruirea căii la modificarea dimensiunilor View.

lineCap = .round adaugă capete rotunjite arcului, conferind indicatorului un aspect mai îngrijit. Proprietatea strokeEnd este o proprietate animabilă a CAShapeLayer care nu necesită redesenarea întregului contur în fiecare cadru. Animația este executată complet pe GPU prin Core Animation, asigurând 60 FPS fără încărcarea CPU.

Întrebări frecvente

Cu ce diferă UIBezierPath de CGPath?

UIBezierPath — îmbrăcămintea orientată pe obiecte a CGPath care conține metode încorporate fill() și stroke(). CGPath este un obiect C nemodificabil al Core Graphics care necesită desenare explicită prin CGContext. UIBezierPath este mai convenabil pentru UIKit, CGPath este mai performant pentru reutilizare.

Cum să rotunjesc doar colțurile superioare ale unui dreptunghi?

Utilizați init(roundedRect:byRoundingCorners:cornerRadii:) cu parametrul .topLeft și .topRight pentru roundedRect. Aceasta este singura metodă UIBezierPath care permite rotunjirea selectivă a colțurilor fără a crea o cale compusă complexă.

Cum să reutilizez UIBezierPath cu stiluri diferite?

Proprietatea cgPath returnează un CGPathRef imutabil care poate fi transmis către CAShapeLayer sau folosit cu culori și grosimi diferite. Modificările UIBezierPath (mutarea punctelor) nu afectează cgPath-ul obținut anterior până la actualizarea explicită.

De ce fill() nu umple întreaga cale?

Verificați usesEvenOddFillRule — dacă conturul are auto-intersectări, regula even-odd poate lăsa zone neumplute. Setați usesEvenOddFillRule = false pentru regula standard de umplere non-zero winding.

Cum să animez forma UIBezierPath?

Utilizați CABasicAnimation cu calea cheie “path” pe CAShapeLayer. Ambele stări ale căii trebuie să conțină același număr de segmente și puncte de control — în caz contrar animația va fi sacadată sau nu va funcționa.

Rezumat

  • UIBezierPath — clasa orientată pe obiecte a UIKit pentru lucrul cu contururi vectoriale și grafică 2D.
  • move(to:) și addLine(to:) — metodele de bază pentru construirea liniilor drepte și poligoanelor.
  • addQuadCurve și addCurve creează curbe Bézier pătratice și cubice cu unul și două puncte de control.
  • addArc desenează arcuri de cerc cu gestionare flexibilă a unghiurilor și direcției.
  • fill() și stroke() execută desenarea direct în contextul grafic curent.
  • Inițializatorii init(roundedRect:) și init(ovalIn:) accelerează crearea figurilor standard.
  • Proprietatea cgPath permite integrarea UIBezierPath cu Core Animation și CAShapeLayer pentru animație.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și