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 выполняет рендеринг градиента с альфа-композитингом и сглаживанием (antialiasing)

Что такое 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: градиент расходится из одной точки. Радиальные градиенты используются для имитации источников света, линз, небесных тел и spotlight-эффектов.

Создание 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 предоставляет несколько дополнительных механизмов управления градиентами: сглаживание (antialiasing), маскирование через обтравочную маску (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) {
    // 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 и 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также