CGGradient: ce este, tipuri de gradiente și crearea lor

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

CGGradient — este un obiect Core Graphics care reprezintă o tranziție lină între două sau mai multe culori. Spre deosebire de desenarea unui gradient printr-un buclă cu schimbarea culorii, CGGradient utilizează calcul accelerator hardware și suportă două tipuri: liniar (axial) și radial (radial). Conform Apple Documentation (2026), CGGradient este folosit pentru crearea de umpluturi realiste, efecte de fundal și simularea surselor de lumină în interfețele iOS și macOS.

Principalele puncte

  • CGGradient — obiect Core Graphics pentru crearea tranzițiilor line de culoare între puncte
  • Gradient liniar (axial) — tranziție de culoare de-a lungul unei linii drepte între punctul de start și cel de final
  • Gradient radial (radial) — tranziție de culoare de la punctul central către cercul exterior
  • Gradientul se creează dintr-un tablou de culori CGColor și un tablou de poziții corespunzătoare (locations) de la 0.0 la 1.0
  • Core Graphics efectuează randarea gradientului cu compozitare alfa și netezire (antialiasing)

Ce este CGGradient?

CGGradient — este un obiect imutabil în Core Graphics, care încapsulează un set de culori și regulile de amestecare a acestora de-a lungul tranziției de gradient. Intern, CGGradient stochează un tablou CGColor, un tablou de poziții (locations) în intervalul [0.0, 1.0] și o referință către CGColorSpace în care sunt interpretate culorile. Fiecare culoare este asociată cu o poziție pe scara gradientului: poziția 0.0 corespunde începutului, 1.0 — sfârșitului tranziției.

La crearea CGGradient prin funcția CGGradientCreateWithColors, Core Graphics efectuează precalcularea valorilor intermediare ale culorilor. Gradientul poate conține un număr arbitrar de opriri de culoare (color stops), permițând crearea de tranziții multicolore complexe. Numărul de culori trebuie să fie de cel puțin două, iar fiecărei culori trebuie să îi corespundă o poziție în tabloul locations.

Arhitectura CGGradient diferă de API-urile de nivel superior, cum ar fi CAGradientLayer din Core Animation, prin faptul că operează direct în contextul grafic Core Graphics. Aceasta oferă control complet asupra procesului de desenare și posibilitatea de a combina gradientele cu alte operații Quartz 2D — măști de decupare, umbre și transformări.

Gradiente liniare și radiale

Core Graphics suportă două tipuri de gradiente: liniar (axial) și radial (radial). Gradientul liniar este creat de funcția CGGradientCreateWithColors și desenat prin CGContextDrawLinearGradient. Gradientul radial necesită aceeași structură CGGradient, dar este desenat prin CGContextDrawRadialGradient.

TipFuncția de desenareParametriAplicație
LiniarCGContextDrawLinearGradientstartPoint, endPoint, optionsFundaluri, butoane, bare de progres
RadialCGContextDrawRadialGradientstartCenter, startRadius, endCenter, endRadius, optionsStrăluciri, surse de lumină, umbre

Gradient liniar (Axial)

Gradientul liniar întinde tranziția de culoare de-a lungul unei linii drepte de la punctul de start startPoint până la punctul final endPoint. Culorile sunt interpolate între aceste două puncte, iar în afara limitelor lor, comportamentul este controlat de opțiunile de extindere. Gradientul liniar este ideal pentru crearea de fundaluri line, simularea suprafețelor metalice și tranziții de culoare în elementele de interfață.

Gradient radial (Radial)

Gradientul radial creează o tranziție de culoare de la un cerc la altul. Fiecare cerc este definit de centru (startCenter / endCenter) și rază (startRadius / endRadius). Culoarea este interpolată de la cercul interior la cel exterior. Un caz particular — când raza de start este 0: gradientul se răspândește dintr-un singur punct. Gradientele radiale sunt folosite pentru simularea surselor de lumină, lentilelor, corpurilor cerești și efectelor de spotlight.

Crearea CGGradient: culori și poziții

CGGradient este creat doar de o singură funcție de bază — CGGradientCreateWithColors. Funcția primește CGColorSpace, un tablou CGColor (CFArray) și un tablou CGFloat locations. Dacă locations este NULL, culorile sunt distribuite uniform pe scara gradientului. Dacă locations este specificat, lungimea sa trebuie să coincidă cu numărul de culori.

Tabloul locations conține valori de la 0.0 la 1.0, determinând punctele de oprire ale fiecărei culori. Valorile trebuie să crească monoton. Dacă prima valoare este mai mare decât 0.0, culoarea de la început până la această poziție este extrapolată din culoarea de la poziția 0.0. În mod similar pentru ultima valoare mai mică de 1.0. Acest comportament este controlat de opțiunile de extindere la desenare.

La alegerea culorilor pentru gradient, este important să se ia în considerare spațiul de culoare. Toate culorile dintr-un CGGradient trebuie să aparțină aceluiași CGColorSpace — Core Graphics efectuează interpolarea componentelor în acest spațiu. Dacă culorile au fost create în spații diferite, ele trebuie convertite în prealabil la un spațiu comun prin CGColorCreateCopyByMatchingToColorSpace.

Desenarea gradientului în context

Core Graphics oferă două funcții pentru desenarea gradientului: CGContextDrawLinearGradient pentru cel liniar și CGContextDrawRadialGradient pentru cel radial. Ambele funcții primesc contextul grafic, obiectul CGGradient, opțiunile de extindere și parametrii geometrici specifici tipului. Desenarea se efectuează ținând cont de masca de decupare curentă (clip) și transformarea contextului.

Opțiuni de extindere (Gradient Options)

Opțiunile de extindere controlează comportamentul gradientului în afara intervalului de poziții 0.0–1.0. Constanta kCGGradientDrawsBeforeStartLocation umple zona dinaintea poziției de start cu culoarea primei opriri. kCGGradientDrawsAfterEndLocation — cu culoarea ultimei opriri. Aceste opțiuni pot fi combinate printr-o mască de biți. Pentru gradientul radial, opțiunile se aplică zonei din afara razelor de start și final.

Influența transformărilor

Gradientul se desenează în sistemul de coordonate al contextului grafic curent, ținând cont de transformarea sa (CTM — Current Transformation Matrix). Aplicarea CGContextTranslateCTM, CGContextScaleCTM sau CGContextRotateCTM înainte de apelarea funcției de desenare modifică poziția și scara gradientului. Aceasta permite reutilizarea unui singur CGGradient pentru diferite zone fără a crea obiecte noi.

Opțiuni: extindere, netezire și mascare

Core Graphics oferă câteva mecanisme suplimentare pentru gestionarea gradientelor: netezire (antialiasing), mascare prin masca de decupare (clipping mask) și combinarea cu efecte de transparență. Netezirea este activată implicit în contextul grafic și este controlată prin CGContextSetShouldAntialias.

Masca de decupare permite limitarea zonei de desenare a gradientului la o formă arbitrară. Înainte de apelarea CGContextDrawLinearGradient trebuie definit un contur prin CGContextBeginPath, CGContextAddPath și CGContextClip. Gradientul va fi desenat doar în interiorul zonei limitate de acest contur. Aceasta este utilizată pe scară largă pentru crearea de icoane gradiente, butoane și bare de progres.

Extinderea gradientului (extend) — un alt parametru important. La utilizarea kCGGradientDrawsBeforeStartLocation, Core Graphics extrapolează culoarea primei opriri pe întreaga zonă până la startPoint. Fără această opțiune, zona din afara gradientului rămâne neumplută (transparentă). Combinarea ambelor opțiuni garantează că întregul dreptunghi al contextului grafic va fi umplut cu gradient, chiar dacă startPoint și endPoint se află în interiorul său.

Exemple de cod în Swift

Să examinăm exemple practice de creare și desenare a gradientelor în iOS folosind CGGradient și Core Graphics.

Gradient liniar cu trei culori

Exemplul creează un gradient liniar cu trei culori (albastru, verde, roșu) și îl desenează pe diagonala UIView. Tabloul locations distribuie culorile inegal: albastru de la 0.0 la 0.3, verde la 0.6, roșu de la 0.6 la 1.0.

swift
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])
}

Gradient radial cu efect de strălucire

Exemplul desenează un gradient radial care simulează strălucirea. Punctul de start cu rază zero definește centrul strălucirii, iar cercul exterior — limita de atenuare. Un astfel de efect este folosit pentru iluminarea elementelor de interfață sau a indicatorilor de activitate.

swift
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])
}

Gradient cu mască de decupare

În acest exemplu, gradientul este limitat la o zonă circulară printr-un contur de decupare. Înainte de desenarea gradientului, se definește un traseu circular care devine masca curentă a contextului. Gradientul umple doar zona din interiorul cercului, creând efectul de icoană gradientă.

swift
func drawGradientInCircle(in ctx: CGContext,
                          rect: CGRect) {
    // Crearea traseului circular de decupare
    let circlePath = CGMutablePath()
    circlePath.addEllipse(in: rect)
    ctx.addPath(circlePath)
    ctx.clip()

    // Desenarea gradientului în interiorul măștii de decupare
    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])
}

Întrebări frecvente

Care este diferența dintre CGGradient și CAGradientLayer?

CGGradient — este un obiect de nivel scăzut Core Graphics pentru desenare în contextul grafic. CAGradientLayer — este un strat de nivel înalt Core Animation cu animație automată și accelerare hardware. CAGradientLayer este mai simplu de utilizat pentru UIKit, dar CGGradient oferă control complet și compatibilitate cu orice CGContext.

Câte culori pot fi adăugate în CGGradient?

Numărul minim — 2 culori. Limita superioară este restricționată doar de memoria disponibilă, deoarece Core Graphics stochează un tablou de culori și un tabel de interpolare precalculat. În practică, mai mult de 10–15 culori într-un singur gradient sunt inutile — tranziția vizuală devine imposibil de distins de una lină.

Cum se face un gradient cu transparență?

Utilizați CGColor cu canal alfa mai mic de 1.0 în tabloul de culori. De exemplu, culoarea cu transparență se creează ca UIColor(red: 0, green: 0, blue: 1, alpha: 0.5).cgColor. Core Graphics interpolează canalul alfa la fel ca componentele de culoare, creând o tranziție lină a transparenței.

Funcționează CGGradient pe macOS?

Da, CGGradient face parte din Core Graphics, disponibil pe ambele platforme: iOS și macOS. Pe macOS, gradientul este desenat în orice NSView prin suprascrierea drawRect. Toate funcțiile CGGradientCreateWithColors, CGContextDrawLinearGradient și CGContextDrawRadialGradient sunt identice pe ambele platforme.

Cum se rotește un gradient?

Pentru a roti gradientul, aplicați o transformare contextului grafic înainte de desenare: CGContextRotateCTM(ctx, angle). Punctele start și end ale gradientului sunt definite în sistemul de coordonate local al contextului după transformare. Alternativ, se pot calcula coordonatele rotite ale punctelor direct fără a modifica CTM.

Rezumat

  • CGGradient — obiect imutabil Core Graphics pentru tranziții line între culori
  • Gradientul liniar se desenează de-a lungul unei linii drepte între startPoint și endPoint prin CGContextDrawLinearGradient
  • Gradientul radial se desenează de la un cerc la altul prin CGContextDrawRadialGradient
  • Gradientul se creează dintr-un tablou CGColor și un tablou de poziții locations (0.0–1.0)
  • Opțiunile de extindere kCGGradientDrawsBeforeStartLocation și kCGGradientDrawsAfterEndLocation controlează umplerea în afara intervalului
  • Masca de decupare (clip) limitează zona de desenare a gradientului la un contur arbitrar
  • Transformările contextului (CTM) afectează poziția, scara și rotația gradientului

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