CGGradient: какво е, типове градиенти и тяхното създаване

Автор: IT Sectr Публикувано: 2026-07-21 Време за четене: 9 мин

CGGradient — е обект на Core Graphics, представляващ плавен преход между два или повече цвята. За разлика от рисуването на градиент чрез цикъл с промяна на цвета, CGGradient използва хардуерно ускорено изчисление и поддържа два типа: линеен (axial) и радиален (radial). Според Apple Documentation (2026), CGGradient се прилага за създаване на реалистични запълвания, фонони ефекти и симулация на източници на светлина в интерфейсите на iOS и macOS.

Основни точки

  • CGGradient — обект на Core Graphics за създаване на плавни цветови преходи между точки
  • Линеен градиент (axial) — цветови преход по права линия между началната и крайната точка
  • Радиален градиент (radial) — цветови преход от централната точка към външния кръг
  • Градиентът се създава от масив от цветове CGColor и масив от съответстващи позиции (locations) от 0.0 до 1.0
  • Core Graphics извършва рендиране на градиента с алфа композитинг и изглаждане (антиалиасинг)

Какво е CGGradient?

CGGradient — е неизменяем обект в Core Graphics, който капсулира набор от цветове и правилата за тяхното смесване по дължината на градиентния преход. Вътрешно CGGradient съхранява масив от CGColor, масив от позиции (locations) в диапазона [0.0, 1.0] и препратка към CGColorSpace, в който се интерпретират цветовете. Всеки цвят е свързан с позиция на скалата на градиента: позиция 0.0 съответства на началото, 1.0 — на края на прехода.

При създаване на CGGradient чрез функцията CGGradientCreateWithColors, Core Graphics извършва предварително изчисление на междинните стойности на цветовете. Градиентът може да съдържа произволен брой цветови спирания (color stops), което позволява създаване на сложни многоцветни преходи. Броят на цветовете трябва да бъде най-малко две и на всеки цвят трябва да съответства позиция в масива locations.

Архитектурата на CGGradient се различава от API на по-високо ниво, като CAGradientLayer от Core Animation, по това, че работи директно в графичния контекст на Core Graphics. Това дава пълен контрол върху процеса на рисуване и възможност за комбиниране на градиенти с други операции на Quartz 2D — изрязащи маски, сенки и трансформации.

Линейни и радиални градиенти

Core Graphics поддържа два типа градиенти: линеен (axial) и радиален (radial). Линейният градиент се създава от функцията CGGradientCreateWithColors и се рисува чрез CGContextDrawLinearGradient. Радиалният градиент изисква същата структура CGGradient, но се рисува чрез CGContextDrawRadialGradient.

ТипФункция за рисуванеПараметриПриложение
ЛинеенCGContextDrawLinearGradientstartPoint, endPoint, optionsФонове, бутони, ленти за напредък
РадиаленCGContextDrawRadialGradientstartCenter, startRadius, endCenter, endRadius, optionsОтблясъци, източници на светлина, сенки

Линеен градиент (Axial)

Линейният градиент разтяга цветовия преход по права линия от началната точка startPoint до крайната endPoint. Цветовете се интерполират между тези две точки, а извън техните граници поведението се управлява от опциите за удължаване. Линейният градиент е идеален за създаване на гладки фонове, симулация на метални повърхности и цветови преходи в елементи на интерфейса.

Радиален градиент (Radial)

Радиалният градиент създава цветови преход от един кръг към друг. Всеки кръг се определя от център (startCenter / endCenter) и радиус (startRadius / endRadius). Цветът се интерполира от вътрешния кръг към външния. Специален случай — когато началният радиус е 0: градиентът се разпространява от една точка. Радиалните градиенти се използват за симулация на източници на светлина, лещи, небесни тела и ефекти на прожектор.

Създаване на CGGradient: цветове и позиции

CGGradient се създава само от една основна функция — CGGradientCreateWithColors. Функцията приема CGColorSpace, масив от CGColor (CFArray) и масив от CGFloat locations. Ако locations е NULL, цветовете се разпределят равномерно по скалата на градиента. Ако locations е зададен, дължината му трябва да съвпада с броя на цветовете.

Масивът locations съдържа стойности от 0.0 до 1.0, определящи точките на спиране на всеки цвят. Стойностите трябва да нарастват монотонно. Ако първата стойност е по-голяма от 0.0, цветът от началото до тази позиция се екстраполира от цвета на позиция 0.0. Аналогично за последната стойност по-малка от 1.0. Това поведение се управлява от опциите за удължаване при рисуване.

При избора на цветове за градиента е важно да се вземе предвид цветовото пространство. Всички цветове в един CGGradient трябва да принадлежат към едно и също CGColorSpace — Core Graphics извършва интерполация на компонентите в това пространство. Ако цветовете са създадени в различни пространства, те трябва предварително да бъдат преобразувани към общо пространство чрез CGColorCreateCopyByMatchingToColorSpace.

Рисуване на градиент в контекст

Core Graphics предоставя две функции за рисуване на градиент: CGContextDrawLinearGradient за линеен и CGContextDrawRadialGradient за радиален. И двете функции приемат графичен контекст, обект CGGradient, опции за удължаване и специфични за типа геометрични параметри. Рисуването се извършва, като се взема предвид текущата изрязаща маска (clip) и трансформацията на контекста.

Опции за удължаване (Gradient Options)

Опциите за удължаване управляват поведението на градиента извън диапазона на позициите 0.0–1.0. Константата kCGGradientDrawsBeforeStartLocation запълва областта преди началната позиция с цвета на първото спиране. kCGGradientDrawsAfterEndLocation — с цвета на последното спиране. Тези опции могат да се комбинират чрез битова маска. За радиален градиент опциите се прилагат към областта извън началния и крайния радиус.

Влияние на трансформациите

Градиентът се рисува в координатната система на текущия графичен контекст, като се взема предвид неговата трансформация (CTM — Current Transformation Matrix). Прилагането на CGContextTranslateCTM, CGContextScaleCTM или CGContextRotateCTM преди извикването на функцията за рисуване променя позицията и мащаба на градиента. Това позволява повторно използване на един CGGradient за различни области без създаване на нови обекти.

Опции: удължаване, изглаждане и маскиране

Core Graphics предоставя няколко допълнителни механизма за управление на градиенти: изглаждане (антиалиасинг), маскиране чрез изрязаща маска (clipping mask) и комбиниране с ефекти на прозрачност. Изглаждането е включено по подразбиране в графичния контекст и се управлява чрез CGContextSetShouldAntialias.

Изрязащата маска позволява ограничаване на областта за рисуване на градиента до произволна форма. Преди извикването на CGContextDrawLinearGradient трябва да се дефинира контур чрез CGContextBeginPath, CGContextAddPath и CGContextClip. Градиентът ще бъде нарисуван само вътре в областта, ограничена от този контур. Това се използва широко за създаване на градиентни икони, бутони и ленти за напредък.

Удължаването на градиента (extend) — още един важен параметър. При използване на kCGGradientDrawsBeforeStartLocation, Core Graphics екстраполира цвета на първото спиране върху цялата област до startPoint. Без тази опция областта извън градиента остава незапълнена (прозрачна). Комбинацията от двете опции гарантира, че целият правоъгълник на графичния контекст ще бъде запълнен с градиент, дори ако startPoint и endPoint се намират вътре в него.

Примери за код в Swift

Нека разгледаме практически примери за създаване и рисуване на градиенти в iOS с помощта на CGGradient и Core Graphics.

Линеен градиент с три цвята

Примерът създава линеен градиент с три цвята (син, зелен, червен) и го рисува по диагонала на UIView. Масивът locations разпределя цветовете неравномерно: син от 0.0 до 0.3, зелен на 0.6, червен от 0.6 до 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])
}

Радиален градиент с ефект на сияние

Примерът рисува радиален градиент, имитиращ сияние. Началната точка с нулев радиус задава центъра на сиянието, а външният кръг — границата на затихване. Такъв ефект се използва за осветяване на елементи на интерфейса или индикатори за активност.

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

Градиент с изрязаща маска

В този пример градиентът е ограничен до кръгла област чрез изрязващ контур. Преди рисуването на градиента се дефинира кръгъл път, който става текущата маска на контекста. Градиентът запълва само областта вътре в кръга, създавайки ефект на градиентна икона.

swift
func drawGradientInCircle(in ctx: CGContext,
                          rect: CGRect) {
    // Създаване на кръгъл изрязващ път
    let circlePath = CGMutablePath()
    circlePath.addEllipse(in: rect)
    ctx.addPath(circlePath)
    ctx.clip()

    // Рисуване на градиент вътре в изрязащата маска
    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])
}

Често задавани въпроси

Каква е разликата между CGGradient и CAGradientLayer?

CGGradient — е нискоников обект на Core Graphics за рисуване в графичен контекст. CAGradientLayer — е високоников слой на Core Animation с автоматична анимация и хардуерно ускорение. CAGradientLayer е по-лесен за използване в UIKit, но CGGradient дава пълен контрол и съвместимост с всеки CGContext.

Колко цвята могат да се добавят в CGGradient?

Минималният брой — 2 цвята. Горната граница е ограничена само от наличната памет, тъй като Core Graphics съхранява масив от цветове и предварително изчислена таблица за интерполация. На практика повече от 10–15 цвята в един градиент не са целесъобразни — визуалният преход става неразличим от плавен.

Как да направим градиент с прозрачност?

Използвайте CGColor с алфа канал по-малък от 1.0 в масива от цветове. Например цвят с прозрачност се създава като UIColor(red: 0, green: 0, blue: 1, alpha: 0.5).cgColor. Core Graphics интерполира алфа канала по същия начин като цветовите компоненти, създавайки плавен преход на прозрачност.

Работи ли CGGradient на macOS?

Да, CGGradient е част от Core Graphics, достъпна на двете платформи: iOS и macOS. На macOS градиентът се рисува във всеки NSView чрез предефиниране на drawRect. Всички функции CGGradientCreateWithColors, CGContextDrawLinearGradient и CGContextDrawRadialGradient са идентични на двете платформи.

Как да завъртим градиент?

За завъртане на градиента приложете трансформация към графичния контекст преди рисуване: CGContextRotateCTM(ctx, angle). Точките start и end на градиента се задават в локалната координатна система на контекста след трансформацията. Алтернативно могат да се изчислят завъртените координати на точките директно без промяна на CTM.

Резюме

  • CGGradient — неизменяем обект на Core Graphics за плавен преход между цветове
  • Линейният градиент се рисува по права линия между startPoint и endPoint чрез CGContextDrawLinearGradient
  • Радиалният градиент се рисува от един кръг към друг чрез CGContextDrawRadialGradient
  • Градиентът се създава от масив CGColor и масив от позиции locations (0.0–1.0)
  • Опциите за удължаване kCGGradientDrawsBeforeStartLocation и kCGGradientDrawsAfterEndLocation управляват запълването извън диапазона
  • Изрязащата маска (clip) ограничава областта за рисуване на градиента до произволен контур
  • Трансформациите на контекста (CTM) влияят на позицията, мащаба и завъртането на градиента

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също