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: градієнт розходиться з однієї точки. Радіальні градієнти використовуються для імітації джерел світла, лінз, небесних тіл та spotlight-ефектів.
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 надає кілька додаткових механізмів керування градієнтами: згладжування (antialiasing), маскування через обрізну маску (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) {
// 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])
}
Поширені запитання
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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також