CGGradient è un oggetto di Core Graphics che rappresenta una transizione graduale tra due o più colori. A differenza del disegno di un gradiente tramite un ciclo con cambio di colore, CGGradient utilizza il calcolo accelerato via hardware e supporta due tipi: lineare (assiale) e radiale. Secondo la Documentazione Apple (2026), CGGradient viene utilizzato per creare riempimenti realistici, effetti di sfondo e simulare fonti di luce nelle interfacce iOS e macOS.
Punti Chiave
CGGradient è un oggetto immutabile in Core Graphics che incapsula un insieme di colori e regole per mescolarli lungo una transizione gradiente. Internamente, CGGradient memorizza un array di CGColor, un array di posizioni (locations) nell'intervallo [0.0, 1.0] e un riferimento al CGColorSpace in cui i colori vengono interpretati. Ogni colore è associato a una posizione sulla scala del gradiente: la posizione 0.0 corrisponde all'inizio, 1.0 alla fine della transizione.
Quando si crea un CGGradient tramite la funzione CGGradientCreateWithColors, Core Graphics precalcola i valori di colore intermedi. Un gradiente può contenere un numero arbitrario di arresti di colore (color stops), consentendo transizioni complesse a più colori. Il numero di colori deve essere almeno due e ogni colore deve corrispondere a una posizione nell'array locations.
L'architettura di CGGradient differisce dalle API di livello superiore come CAGradientLayer di Core Animation perché lavora direttamente nel contesto di Core Graphics. Ciò fornisce il controllo completo sul processo di disegno e la capacità di combinare gradienti con altre operazioni Quartz 2D — maschere di ritaglio, ombre e trasformazioni.
Core Graphics supporta due tipi di gradienti: lineare (assiale) e radiale. Un gradiente lineare viene creato con la funzione CGGradientCreateWithColors e disegnato con CGContextDrawLinearGradient. Un gradiente radiale richiede la stessa struttura CGGradient ma viene disegnato con CGContextDrawRadialGradient.
| Tipo | Funzione di disegno | Parametri | Utilizzo |
|---|---|---|---|
| Lineare | CGContextDrawLinearGradient | startPoint, endPoint, options | Sfondi, pulsanti, barre di progresso |
| Radiale | CGContextDrawRadialGradient | startCenter, startRadius, endCenter, endRadius, options | Riflessi, fonti di luce, ombre |
Gradiente lineare estende la transizione di colore lungo una linea retta dal punto iniziale startPoint al punto finale endPoint. I colori vengono interpolati tra questi due punti e il comportamento al di là di essi è controllato dalle opzioni di estensione. Il gradiente lineare è ideale per creare sfondi morbidi, simulare superfici metalliche e transizioni di colore negli elementi dell'interfaccia.
Gradiente radiale crea una transizione di colore da un cerchio a un altro. Ogni cerchio è definito da un centro (startCenter / endCenter) e un raggio (startRadius / endRadius). Il colore viene interpolato dal cerchio interno a quello esterno. Un caso speciale è quando il raggio iniziale è 0: il gradiente si irradia da un singolo punto. I gradienti radiali vengono utilizzati per simulare fonti di luce, lenti, corpi celesti ed effetti spotlight.
CGGradient viene creato con una sola funzione base — CGGradientCreateWithColors. La funzione accetta un CGColorSpace, un array di CGColor (CFArray) e un array di CGFloat locations. Se locations è NULL, i colori vengono distribuiti uniformemente lungo la scala del gradiente. Se locations sono specificate, il loro numero deve corrispondere al numero di colori.
L'array locations contiene valori da 0.0 a 1.0 che definiscono i punti di arresto per ogni colore. I valori devono aumentare in modo monotono. Se il primo valore è maggiore di 0.0, il colore dall'inizio fino a questa posizione viene estrapolato dal colore alla posizione 0.0. Analogamente per l'ultimo valore inferiore a 1.0. Questo comportamento è controllato dalle opzioni di estensione durante il disegno.
Quando si scelgono i colori per un gradiente, è importante considerare lo spazio colore. Tutti i colori in un singolo CGGradient devono appartenere allo stesso CGColorSpace — Core Graphics interpola i componenti in quello spazio. Se i colori vengono creati in spazi diversi, devono essere prima convertiti in uno spazio comune tramite CGColorCreateCopyByMatchingToColorSpace.
Core Graphics fornisce due funzioni per disegnare un gradiente: CGContextDrawLinearGradient per lineare e CGContextDrawRadialGradient per radiale. Entrambe le funzioni accettano un contesto grafico, un oggetto CGGradient, opzioni di estensione e parametri geometrici specifici del tipo. Il disegno viene eseguito tenendo conto della maschera di ritaglio corrente e della trasformazione del contesto.
Le opzioni di estensione controllano il comportamento del gradiente oltre l'intervallo di posizioni 0.0–1.0. La costante kCGGradientDrawsBeforeStartLocation riempie l'area prima della posizione iniziale con il colore del primo arresto. kCGGradientDrawsAfterEndLocation riempie con il colore dell'ultimo arresto. Queste opzioni possono essere combinate tramite una maschera di bit. Per i gradienti radiali, le opzioni si applicano all'area oltre i raggi iniziale e finale.
Il gradiente viene disegnato nel sistema di coordinate del contesto grafico corrente, tenendo conto della sua trasformazione (CTM — Current Transformation Matrix). L'applicazione di CGContextTranslateCTM, CGContextScaleCTM o CGContextRotateCTM prima di chiamare la funzione di disegno modifica la posizione e la scala del gradiente. Ciò consente di riutilizzare un singolo CGGradient per aree diverse senza creare nuovi oggetti.
Core Graphics fornisce diversi meccanismi aggiuntivi per controllare i gradienti: anti-aliasing, mascheramento tramite maschera di ritaglio (clipping mask) e combinazione con effetti di trasparenza. L'anti-aliasing è abilitato per impostazione predefinita nel contesto grafico e viene controllato tramite CGContextSetShouldAntialias.
Maschera di ritaglio consente di limitare l'area di disegno del gradiente a una forma arbitraria. Prima di chiamare CGContextDrawLinearGradient, è necessario definire un percorso tramite CGContextBeginPath, CGContextAddPath e CGContextClip. Il gradiente viene disegnato solo all'interno dell'area delimitata da questo percorso. Questo è ampiamente utilizzato per creare icone gradiente, pulsanti e barre di progresso.
Estensione del gradiente è un altro parametro importante. Quando si utilizza kCGGradientDrawsBeforeStartLocation, Core Graphics estrapola il colore del primo arresto su tutta l'area prima di startPoint. Senza questa opzione, l'area al di fuori del gradiente rimane non riempita (trasparente). La combinazione di entrambe le opzioni garantisce che l'intero rettangolo del contesto grafico venga riempito con un gradiente, anche se startPoint e endPoint si trovano al suo interno.
Vediamo esempi pratici di creazione e disegno di gradienti in iOS utilizzando CGGradient e Core Graphics.
Questo esempio crea un gradiente lineare con tre colori (blu, verde, rosso) e lo disegna diagonalmente attraverso una UIView. L'array locations distribuisce i colori in modo non uniforme: blu da 0.0 a 0.3, verde a 0.6, rosso da 0.6 a 1.0.
func drawLinearGradient(in ctx: CGContext,
rect: CGRect) {
let colors = [
UIColor.blue.cgColor,
UIColor.green.cgColor,
UIColor.red.cgColor
] as CFArray
let locations: [CGFloat] = [0.0, 0.6, 1.0]
let space = CGColorSpaceCreateDeviceRGB()
guard let gradient = CGGradientCreateWithColors(
space, colors, locations
) else { return }
let start = CGPoint(x: 0, y: 0)
let end = CGPoint(x: rect.width,
y: rect.height)
ctx.drawLinearGradient(gradient,
start: start, end: end,
options: [.drawsBeforeStartLocation,
.drawsAfterEndLocation])
}
Questo esempio disegna un gradiente radiale che simula un effetto bagliore. Il punto iniziale con raggio zero definisce il centro del bagliore e il cerchio esterno definisce il limite di dissolvenza. Questo effetto viene utilizzato per evidenziare elementi dell'interfaccia o indicatori di attività.
func drawRadialGlow(in ctx: CGContext,
center: CGPoint) {
let colors = [
UIColor.white.cgColor,
UIColor.orange.cgColor,
UIColor.clear.cgColor
] as CFArray
let locations: [CGFloat] = [0.0, 0.4, 1.0]
let gradient = CGGradientCreateWithColors(
CGColorSpaceCreateDeviceRGB(), colors, locations)
ctx.drawRadialGradient(gradient,
startCenter: center, startRadius: 0,
endCenter: center, endRadius: 100,
options: [.drawsBeforeStartLocation,
.drawsAfterEndLocation])
}
In questo esempio, il gradiente è limitato a un'area circolare tramite un percorso di ritaglio. Prima di disegnare il gradiente, viene definito un percorso circolare che diventa la maschera corrente del contesto. Il gradiente riempie solo l'area all'interno del cerchio, creando un effetto icona gradiente.
func drawGradientInCircle(in ctx: CGContext,
rect: CGRect) {
// Creating circular clip path
let circlePath = CGMutablePath()
circlePath.addEllipse(in: rect)
ctx.addPath(circlePath)
ctx.clip()
// Drawing gradient inside clip mask
let colors = [UIColor.magenta.cgColor,
UIColor.cyan.cgColor]
let gradient = CGGradientCreateWithColors(
CGColorSpaceCreateDeviceRGB(),
colors as CFArray, nil)
ctx.drawLinearGradient(gradient,
start: CGPoint(x: 0, y: 0),
end: CGPoint(x: rect.width,
y: rect.height),
options: [.drawsBeforeStartLocation])
}
Domande Frequenti
CGGradient è un oggetto di basso livello di Core Graphics per il disegno in un contesto grafico. CAGradientLayer è un livello di alto livello di Core Animation con animazione automatica e accelerazione hardware. CAGradientLayer è più facile da usare con UIKit, ma CGGradient offre il controllo completo e la compatibilità con qualsiasi CGContext.
Minimo sono 2 colori. Il limite superiore è vincolato solo dalla memoria disponibile, poiché Core Graphics memorizza un array di colori e una tabella di interpolazione precalcolata. In pratica, più di 10–15 colori in un singolo gradiente è inutile — la transizione visiva diventa indistinguibile da una graduale.
Utilizzare un CGColor con canale alfa inferiore a 1.0 nell'array di colori. Ad esempio, un colore con trasparenza viene creato come UIColor(red: 0, green: 0, blue: 1, alpha: 0.5).cgColor. Core Graphics interpola il canale alfa proprio come i componenti di colore, creando una transizione di trasparenza graduale.
Sì, CGGradient fa parte di Core Graphics, disponibile su entrambe le piattaforme: iOS e macOS. Su macOS, il gradiente viene disegnato in qualsiasi NSView sovrascrivendo drawRect. Tutte le funzioni CGGradientCreateWithColors, CGContextDrawLinearGradient e CGContextDrawRadialGradient sono identiche su entrambe le piattaforme.
Per ruotare un gradiente, applicare una trasformazione al contesto grafico prima di disegnare: CGContextRotateCTM(ctx, angle). I punti iniziale e finale del gradiente vengono specificati nel sistema di coordinate locale del contesto dopo la trasformazione. In alternativa, è possibile calcolare direttamente le coordinate ruotate dei punti senza modificare il CTM.
Riepilogo
CGContextDrawLinearGradientCGContextDrawRadialGradientSvilupperemo 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.
Leggi anche