CGGradient — е обект на Core Graphics, представляващ плавен преход между два или повече цвята. За разлика от рисуването на градиент чрез цикъл с промяна на цвета, CGGradient използва хардуерно ускорено изчисление и поддържа два типа: линеен (axial) и радиален (radial). Според Apple Documentation (2026), CGGradient се прилага за създаване на реалистични запълвания, фонони ефекти и симулация на източници на светлина в интерфейсите на iOS и macOS.
Основни точки
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.
| Тип | Функция за рисуване | Параметри | Приложение |
|---|---|---|---|
| Линеен | CGContextDrawLinearGradient | startPoint, endPoint, options | Фонове, бутони, ленти за напредък |
| Радиален | CGContextDrawRadialGradient | startCenter, startRadius, endCenter, endRadius, options | Отблясъци, източници на светлина, сенки |
Линейният градиент разтяга цветовия преход по права линия от началната точка startPoint до крайната endPoint. Цветовете се интерполират между тези две точки, а извън техните граници поведението се управлява от опциите за удължаване. Линейният градиент е идеален за създаване на гладки фонове, симулация на метални повърхности и цветови преходи в елементи на интерфейса.
Радиалният градиент създава цветови преход от един кръг към друг. Всеки кръг се определя от център (startCenter / endCenter) и радиус (startRadius / endRadius). Цветът се интерполира от вътрешния кръг към външния. Специален случай — когато началният радиус е 0: градиентът се разпространява от една точка. Радиалните градиенти се използват за симулация на източници на светлина, лещи, небесни тела и ефекти на прожектор.
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) и трансформацията на контекста.
Опциите за удължаване управляват поведението на градиента извън диапазона на позициите 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 се намират вътре в него.
Нека разгледаме практически примери за създаване и рисуване на градиенти в iOS с помощта на CGGradient и Core Graphics.
Примерът създава линеен градиент с три цвята (син, зелен, червен) и го рисува по диагонала на UIView. Масивът locations разпределя цветовете неравномерно: син от 0.0 до 0.3, зелен на 0.6, червен от 0.6 до 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])
}
Примерът рисува радиален градиент, имитиращ сияние. Началната точка с нулев радиус задава центъра на сиянието, а външният кръг — границата на затихване. Такъв ефект се използва за осветяване на елементи на интерфейса или индикатори за активност.
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])
}
В този пример градиентът е ограничен до кръгла област чрез изрязващ контур. Преди рисуването на градиента се дефинира кръгъл път, който става текущата маска на контекста. Градиентът запълва само областта вътре в кръга, създавайки ефект на градиентна икона.
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 — е нискоников обект на Core Graphics за рисуване в графичен контекст. CAGradientLayer — е високоников слой на Core Animation с автоматична анимация и хардуерно ускорение. CAGradientLayer е по-лесен за използване в UIKit, но CGGradient дава пълен контрол и съвместимост с всеки CGContext.
Минималният брой — 2 цвята. Горната граница е ограничена само от наличната памет, тъй като Core Graphics съхранява масив от цветове и предварително изчислена таблица за интерполация. На практика повече от 10–15 цвята в един градиент не са целесъобразни — визуалният преход става неразличим от плавен.
Използвайте CGColor с алфа канал по-малък от 1.0 в масива от цветове. Например цвят с прозрачност се създава като UIColor(red: 0, green: 0, blue: 1, alpha: 0.5).cgColor. Core Graphics интерполира алфа канала по същия начин като цветовите компоненти, създавайки плавен преход на прозрачност.
Да, CGGradient е част от Core Graphics, достъпна на двете платформи: iOS и macOS. На macOS градиентът се рисува във всеки NSView чрез предефиниране на drawRect. Всички функции CGGradientCreateWithColors, CGContextDrawLinearGradient и CGContextDrawRadialGradient са идентични на двете платформи.
За завъртане на градиента приложете трансформация към графичния контекст преди рисуване: CGContextRotateCTM(ctx, angle). Точките start и end на градиента се задават в локалната координатна система на контекста след трансформацията. Алтернативно могат да се изчислят завъртените координати на точките директно без промяна на CTM.
Резюме
CGContextDrawLinearGradientCGContextDrawRadialGradientЩе разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също