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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также