CALayer — це базовий клас графічних шарів в iOS, що входить до складу фреймворку QuartzCore. Кожен UIView в iOS має пов'язаний CALayer, який забезпечує рендеринг контенту, анімацію та композицію на GPU. За даними Apple QuartzCore Documentation, 2025, CALayer підтримує понад 40 анімованих властивостей і працює безпосередньо через Metal. Розуміння CALayer необхідне для створення плавних анімацій та оптимізації продуктивності інтерфейсу.
Головне
CALayer — це клас із фреймворку QuartzCore, який керує растровим зображенням прямокутної області екрана. Він зберігає візуальні властивості: frame, backgroundColor, opacity, shadow, border, transform. На відміну від UIView, CALayer не обробляє події дотику, не бере участі в Auto Layout і не має життєвого циклу view controller.
Архітектурно CALayer реалізує патерн Model у контексті Core Animation. Шар зберігає стан візуальних властивостей, а Core Animation керує інтерполяцією між станами при анімації. Такий поділ дозволяє анімувати будь-які властивості шару без необхідності перемальовувати контент через drawRect.
За даними Apple WWDC 2024, CALayer був переписаний для роботи через Metal. Сучасний pipeline рендерингу включає три етапи: Commit (оновлення властивостей на CPU), Render (генерація команд для GPU на CPU) та Composite (виконання команд на GPU). CALayer бере участь у всіх трьох етапах, надаючи дані для кожного.
Кожен шар може містити sublayers — дочірні шари, які рендеряться поверх батьківського. Ієрархія шарів повторює ієрархію UIView, але може існувати окремо від неї. Розробник може створювати шари незалежно від UIView через CALayer() і додавати їх в ієрархію через addSublayer.
UIView — це надбудова над CALayer, яка додає: обробку дотиків через UIResponder, участь в Auto Layout, представлення в storyboard, інтеграцію з UIViewController. CALayer — це легкий об'єкт, який можна використовувати без UIView для чисто візуальних елементів.
На практиці це означає, що якщо елементу не потрібні дотики та layout, його можна реалізувати як CALayer. Наприклад, фонова анімація, індикатори завантаження, декоративні елементи — все це ефективніше реалізувати через CALayer, уникаючи оверхеду UIView.
Базові властивості CALayer включають фрейм, позиціонування, відображення та візуальні ефекти. frame визначає прямокутну область шару в координатах батька, bounds — внутрішні координати, position — центр шару. Зміна position анімується за замовчуванням через implicit animation.
Властивість contents дозволяє задати растровий вміст шару безпосередньо — через CGImage або CIImage. Це альтернатива малюванню через drawRect: якщо зображення вже готове, його можна передати в contents, і Core Animation відрендерить його без додаткової обробки.
Для анімації використовуються CABasicAnimation, CAKeyframeAnimation та CATransition. Всі ці класи працюють через ключові шляхи властивостей CALayer, що дозволяє анімувати практично будь-який атрибут — від position до transform.rotation.z.
Apple надає кілька спеціалізованих підкласів CALayer, кожен з яких вирішує конкретне завдання. Вибір відповідного підкласу замість базового CALayer може дати значний приріст продуктивності за рахунок апаратного прискорення.
CAReplicatorLayer особливо корисний для створення повторюваних патернів без дублювання коду. Наприклад, індикатор завантаження з 10 точок реалізується одним CAReplicatorLayer з instanceCount = 10 та зміщенням за часом анімації instanceDelay.
Рендеринг CALayer проходить три фази. Commit — при зміні властивості шару на CPU формується пакет змін. Render — Core Animation генерує Metal-команди на CPU на основі властивостей шару. Composite — GPU виконує команди та виводить кадр на екран. Весь процес синхронізований із частотою оновлення дисплея.
При композиції кількох шарів GPU зводить їх у фінальне зображення з урахуванням прозорості, масок та режимів накладання. Якщо шар має opaque = true, Core Animation оптимізує композицію: замість альфа-блендингу виконується проста заміна пікселів, що значно швидше.
За даними Apple Performance Guidelines, основні фактори, що сповільнюють рендеринг CALayer: складна ієрархія sublayers (понад 30 шарів на екрані), використання масок (mask-властивість), автоматичний розрахунок тіні без shadowPath, надмірне використання shouldRasterize для динамічних шарів.
Інструмент Core Animation Instrument в XCode дозволяє моніторити час рендерингу кожного шару, кількість offscreen-буферів та частоту виклику drawRect. Оптимальний час рендерингу для 60 FPS — не більше 8 мс на CPU та 8 мс на GPU.
Offscreen rendering — рендеринг шару в проміжний буфер перед виведенням на екран. Виникає при використанні cornerRadius + masksToBounds з контентом, групової opacity, масок та shouldRasterize. Кожен offscreen-прохід займає 2–5 мс, тому надлишкові offscreen-рендеринги критичні для продуктивності.
Для діагностики offscreen rendering використовуйте інструмент Color Offscreen-Rendered в Core Animation Instrument. Жовті шари — offscreen, сині — прямий рендеринг на екран. Мінімізація offscreen-проходів — ключовий прийом оптимізації в iOS.
Перший приклад демонструє базове налаштування CALayer зі створенням тіні, заокругленням кутів та межею. shadowPath заданий явно для прискорення рендерингу:
import UIKit
func configureLayer(_ view: UIView) {
let layer = view.layer
layer.cornerRadius = 16
layer.borderWidth = 2
layer.borderColor = UIColor.systemBlue.cgColor
layer.backgroundColor = UIColor.white.cgColor
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.2
layer.shadowOffset = CGSize(width: 0, height: 4)
layer.shadowRadius = 8
layer.shadowPath = UIBezierPath(
roundedRect: view.bounds,
cornerRadius: layer.cornerRadius
).cgPath
}
Другий приклад — анімація transform через CABasicAnimation з перспективною 3D-трансформацією. Анімація повороту по осі Y створює ефект перевороту картки:
let flipAnimation = CABasicAnimation(keyPath: "transform")
var transform = CATransform3DIdentity
transform.m34 = -1.0 / 500.0
transform = CATransform3DRotate(transform, .pi, 0, 1, 0)
flipAnimation.toValue = NSValue(caTransform3D: transform)
flipAnimation.duration = 0.8
flipAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
cardLayer.add(flipAnimation, forKey: "flip")
Третій приклад — використання CAGradientLayer для створення фонового градієнта. Градієнт рендериться на GPU і не потребує додаткових ресурсів при зміні розмірів:
func addGradient(to view: UIView, colors: [UIColor]) {
let gradient = CAGradientLayer()
gradient.colors = colors.map { $0.cgColor }
gradient.locations = [0.0, 0.5, 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = view.bounds
view.layer.insertSublayer(gradient, at: 0)
}
Часті запитання
UIView — це надбудова над CALayer, яка додає обробку дотиків, Auto Layout та інтеграцію з UIViewController. CALayer працює тільки з візуальним представленням та анімацією, що робить його більш легким та ефективним для чисто графічних завдань.
Понад 40 властивостей, включаючи position, bounds, frame, opacity, backgroundColor, cornerRadius, transform, shadowOffset, shadowRadius, borderWidth та borderColor. Анімація запускається автоматично при зміні властивості всередині анімаційного блоку UIView.animate.
Задайте shadowPath — явний контур тіні у вигляді UIBezierPath. Без shadowPath Core Animation аналізує альфа-канал контенту для розрахунку форми тіні, що потребує додаткового проходу. З shadowPath тінь рендериться як проста геометрична фігура без аналізу контенту.
Implicit animation — автоматична анімація при зміні анімованої властивості CALayer поза блоком UIView.animate. Тривалість за замовчуванням — 0.25 секунди. Можна вимкнути через CATransaction.setDisableActions(true) або задати свою тривалість через CATransaction.begin/commit.
CAShapeLayer ефективніший, коли потрібно відобразити векторну фігуру — лінію, коло, багатокутник, складний контур. Він рендерить path на GPU без створення окремого растрового буфера. Базовий CALayer підходить для прямокутних областей з фоном, межею та тінню.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також