UIBezierPath: cos'è, metodi di disegno e come funziona

Autore: IT Sectr Pubblicato: 2026-07-21 Tempo di lettura: 8 min

UIBezierPath è una classe di UIKit che incapsula un percorso vettoriale per la grafica 2D in iOS. Combina la descrizione geometrica del contorno con capacità di disegno, consentendo di creare linee, curve di Bézier, archi e rettangoli. A differenza di CGPath, UIBezierPath contiene propri metodi di disegno che lavorano direttamente nel contesto grafico corrente. Secondo Apple Developer Documentation, 2026, UIBezierPath supporta tutte le operazioni standard di Quartz 2D in un wrapper orientato agli oggetti.

Punti chiave

  • UIBezierPath è un wrapper orientato agli oggetti di CGPath per lavorare con percorsi vettoriali in UIKit.
  • move(to:) e addLine(to:) definiscono segmenti di linea retta del percorso.
  • addQuadCurve(to:controlPoint:) e addCurve(to:controlPoint1:controlPoint2:) costruiscono curve di Bézier.
  • addArc(withCenter:radius:startAngle:endAngle:clockwise:) crea archi e settori.
  • fill e stroke disegnano il percorso direttamente nel contesto corrente senza usare oggetti aggiuntivi.

Cos'è UIBezierPath?

UIBezierPath è una classe del framework UIKit che eredita da NSObject e implementa NSCopying, NSSecureCoding. Fornisce un'API Objective-C/Swift di alto livello per creare e disegnare percorsi vettoriali. Internamente, UIBezierPath memorizza un riferimento a CGPathRef un oggetto Core Graphics, ma aggiunge metodi convenienti per il disegno, la modifica della geometria e la gestione degli stili.

Il principale vantaggio di UIBezierPath rispetto all'uso diretto di CGPath sono i metodi di disegno integrati. Chiamare fill() o stroke() su un'istanza di UIBezierPath configura automaticamente il contesto e disegna il percorso. La classe supporta anche le proprietà lineWidth, lineCapStyle, lineJoinStyle, miterLimit e flatness, consentendo di controllare l'aspetto senza un oggetto separato per memorizzare gli stili.

UIBezierPath è utilizzato nella maggior parte delle applicazioni iOS per il disegno personalizzato all'interno di UIView: dalle icone semplici ai grafici animati complessi. Il metodo draw(_:) della classe UIView è il luogo principale in cui gli sviluppatori creano e disegnano UIBezierPath. La classe è completamente compatibile con Core Animation e può essere utilizzata per l'animazione di percorsi tramite CAShapeLayer e CABasicAnimation.

Linee rette e rettangoli

Il metodo move(to:) sposta il punto di partenza del percorso alle coordinate specificate senza disegnare. Questa è una chiamata obbligatoria prima di costruire qualsiasi segmento. addLine(to:) aggiunge un segmento rettilineo dalla posizione corrente al punto indicato. Il metodo close() chiude il contorno disegnando una linea dall'ultimo punto al primo punto dell'ultimo move(to:).

Rettangoli con angoli arrotondati

UIBezierPath fornisce diversi inizializzatori convenienti per forme pronte. init(rect:) crea un rettangolo, init(roundedRect:cornerRadius:) crea un rettangolo con angoli arrotondati. Il parametro UIRectCorner consente di arrotondare solo gli angoli selezionati, come topLeft e bottomRight, lasciando gli altri diritti. Questo è ampiamente utilizzato per creare pulsanti e carte personalizzati.

init(ovalIn:) crea un'ellisse inscritta nel rettangolo specificato. Se il rettangolo è un quadrato, l'ellisse diventa un cerchio. init(roundedRect:byRoundingCorners:cornerRadii:) è l'opzione più flessibile, consentendo di impostare raggi diversi per ogni angolo. Questo inizializzatore è stato introdotto in iOS 6 e rimane lo standard per la creazione di contenitori arrotondati.

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

Curve di Bézier: quadratiche e cubiche

addQuadCurve(to:controlPoint:) aggiunge una curva di Bézier quadratica con un punto di controllo. Questo tipo di curva viene utilizzato per curve morbide semplici quando si desidera minimizzare i calcoli. Una curva quadratica è sempre una parabola ed è garantita all'interno del triangolo formato dai punti di inizio, controllo e fine.

Curve di Bézier cubiche

addCurve(to:controlPoint1:controlPoint2:) aggiunge una curva di Bézier cubica con due punti di controllo. Le curve cubiche sono utilizzate in tutti gli editor vettoriali moderni e nei font TrueType. Due punti di controllo offrono più gradi di libertà per un controllo preciso della forma. Questo metodo è raccomandato per la costruzione di contorni organici e complessi.

Quando si costruiscono curve, è importante mantenere il principio di continuità la morbidezza nel punto di connessione dei segmenti. Per la continuità C1 (tangente), il punto di controllo della curva successiva deve trovarsi sulla stessa linea del punto di controllo della precedente. Per la continuità C2 (curvatura), è necessaria una coordinazione più complessa, che viene automaticamente fornita in CAShapeLayer quando si anima tra due UIBezierPath con lo stesso numero di punti di controllo.

MetodoTipoPunti di controlloGrado
addQuadCurveBézier quadratica12
addCurveBézier cubica23
addArcArco

Archi e circonferenze

addArc(withCenter:radius:startAngle:endAngle:clockwise:) aggiunge un arco di cerchio con i parametri specificati. Gli angoli sono indicati in radianti rispetto al centro del cerchio. L'angolo zero corrisponde alla direzione verso destra (le 3 sul quadrante di un orologio). Il parametro clockwise determina la direzione: true in senso orario, false in senso antiorario. Gli archi sono essenziali per i grafici a torta, i tachimetri e gli anelli di progresso interattivi.

Cerchi e settori

Per un cerchio completo, usa startAngle = 0 e endAngle = .pi * 2. Per creare un settore (come parte di un grafico a torta), usa addArc seguito da addLine(to:) al centro e close(). UIBezierPath non ha un metodo addCircle integrato un cerchio viene creato tramite init(ovalIn:) con un rettangolo quadrato o tramite addArc con un angolo completo.

Il metodo addArc(withCenter:radius:startAngle:endAngle:clockwise:) esegue automaticamente move(to:) al punto di partenza dell'arco se la posizione corrente non corrisponde. Se la posizione corrente differisce, viene disegnata una linea retta tra essa e l'inizio dell'arco. Questo comportamento differisce da Core Graphics, dove è necessario un move(to:) esplicito prima di ogni nuovo contorno.

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

Riempimento e tratto del percorso

fill() riempie l'area interna del percorso con il colore fillColor corrente o il colore impostato nel contesto grafico tramite setFill(). Per percorsi con auto-intersezioni, la regola di riempimento è determinata dalla proprietà usesEvenOddFillRule. Se è true, viene utilizzata la regola pari-dispari: un punto è considerato all'interno della forma se un raggio da esso attraversa il contorno un numero dispari di volte.

Impostazioni del tratto

stroke() disegna il contorno del percorso con le impostazioni correnti di lineWidth, lineCapStyle e lineJoinStyle. lineCapStyle definisce la forma delle estremità dei segmenti aperti: .butt (taglio dritto), .round (semicircolare), .square (quadrato con sporgenza). lineJoinStyle definisce la forma delle giunzioni degli angoli: .miter (acuto), .round (arrotondato), .bevel (smussato).

Per le linee tratteggiate si usa la proprietà setLineDash(_:count:phase:). Accetta un array di lunghezze alternate di tratti e spazi, il numero di elementi e la fase iniziale. Il rendering del tratteggio viene eseguito durante la rasterizzazione del percorso i pattern complessi non aumentano la complessità geometrica del contorno. CAShapeLayer supporta l'animazione della proprietà strokeEnd per un effetto di “disegno” dall'inizio alla fine.

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

Esempio di creazione di una figura complessa

Creiamo un indicatore di progresso personalizzato a forma di anello usando UIBezierPath. L'anello è costruito da due archi dello stesso raggio con diversi colori di tratto. Il primo arco è un cerchio completo in grigio (sfondo), il secondo è un segmento che mostra il progresso. Per l'animazione si usano CAShapeLayer e 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
    }
}

In questo esempio, UIBezierPath viene utilizzato per creare un contorno circolare, che viene poi passato a CAShapeLayer tramite la proprietà cgPath. L'animazione di strokeEnd da 0 a 1 visualizza il riempimento dell'anello. Questo approccio viene utilizzato negli indicatori di caricamento, nei tracker fitness e nei widget di progresso. Il metodo layoutSubviews garantisce la ricostruzione del percorso quando cambia la dimensione della View.

lineCap = .round aggiunge estremità arrotondate all'arco, dando all'indicatore un aspetto più curato. La proprietà strokeEnd è una proprietà animabile di CAShapeLayer che non richiede di ridisegnare l'intero contorno in ogni fotogramma. L'animazione viene eseguita interamente sulla GPU tramite Core Animation, garantendo 60 FPS senza carico sulla CPU.

Domande frequenti

In cosa differisce UIBezierPath da CGPath?

UIBezierPath è un wrapper orientato agli oggetti attorno a CGPath che contiene metodi fill() e stroke() integrati. CGPath è un oggetto C immutabile di Core Graphics che richiede disegno esplicito tramite CGContext. UIBezierPath è più conveniente per UIKit, mentre CGPath è più performante per il riutilizzo.

Come arrotondare solo gli angoli superiori di un rettangolo?

Usa init(roundedRect:byRoundingCorners:cornerRadii:) con i parametri .topLeft e .topRight per roundedRect. Questo è l'unico metodo di UIBezierPath che consente di arrotondare selettivamente gli angoli senza creare un percorso composto complesso.

Come riutilizzare UIBezierPath con stili diversi?

La proprietà cgPath restituisce un CGPathRef immutabile che può essere passato a CAShapeLayer o utilizzato con diversi colori e spessori. Le modifiche a UIBezierPath (movimento di punti) non influenzano il cgPath ottenuto in precedenza fino a quando non viene esplicitamente aggiornato.

Perché fill() non copre l'intero percorso?

Controlla usesEvenOddFillRule se il contorno ha auto-intersezioni, la regola pari-dispari può lasciare aree non riempite. Imposta usesEvenOddFillRule = false per la regola di riempimento standard non-zero winding.

Come animare una forma UIBezierPath?

Usa CABasicAnimation con il percorso chiave “path” su CAShapeLayer. Entrambi gli stati del percorso devono contenere lo stesso numero di segmenti e punti di controllo altrimenti l'animazione sarà a scatti o fallirà.

Riepilogo

  • UIBezierPath è una classe orientata agli oggetti di UIKit per lavorare con percorsi vettoriali e grafica 2D.
  • move(to:) e addLine(to:) sono metodi di base per costruire linee rette e poligoni.
  • addQuadCurve e addCurve creano curve di Bézier quadratiche e cubiche con uno e due punti di controllo.
  • addArc disegna archi circolari con controllo flessibile di angoli e direzione.
  • fill() e stroke() eseguono il disegno direttamente nel contesto grafico corrente.
  • Gli inizializzatori init(roundedRect:) e init(ovalIn:) accelerano la creazione di forme standard.
  • La proprietà cgPath consente di integrare UIBezierPath con Core Animation e CAShapeLayer per l'animazione.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche