CAShapeLayer — шта је то, својства и креирање облика

Аутор: IT Sectr Објављено: 2026-06-12 Време читања: 10 мин

CAShapeLayer — је подкласа CALayer-а намењена хардверском рендеровању векторских контура на GPU-у. За разлику од основног CALayer-а, који ради са растерским сликама преко contents, CAShapeLayer рендерује произвољне облике задате кроз CGPath без креирања засебног offscreen бафера. Према Apple QuartzCore Documentation, 2025, CAShapeLayer користи хардверско убрзање за заглађивање ивица и подржава анимацију path, strokeStart и strokeEnd. Ово је стандардни алат за креирање икона, индикатора напретка и маски у iOS-у.

Главно

  • CAShapeLayer — подкласа CALayer-а за рендеровање векторских облика на GPU-у кроз CGPath.
  • Рендеровање контуре се врши хардверски без креирања међубафера — брже је од Core Graphics.
  • Својства fillColor, strokeColor, lineWidth, lineCap, lineJoin управљају изгледом облика.
  • Анимација path омогућава глатко преобликовање једног облика у други — кључна могућност за UI анимације.
  • strokeStart и strokeEnd се анимирају за стварање ефекта цртања контуре — идеално за индикаторе учитавања.

Шта је CAShapeLayer?

CAShapeLayer — је специјализовани слој за рендеровање векторске графике, представљен у iOS 3.0. За разлику од CALayer-а, који чува растерску слику, CAShapeLayer чува математички опис контуре — CGPath — и рендерује је директно на GPU-у. Ово омогућава скалирање облика без губитка квалитета и анимирање његових својстава без прецртавања садржаја.

Архитектонски, CAShapeLayer наслеђује све могућности CALayer-а: сенке, границе, трансформације, маске. Али додаје специфична својства за рад са контурама: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, miterLimit, strokeStart, strokeEnd и fillRule. Свако од ових својстава може бити анимирано кроз CABasicAnimation.

Према Apple Documentation, CAShapeLayer користи хардверско убрзање при рендеровању. За разлику од цртања кроз Core Graphics у drawRect:, где CPU рендерује контуру у растерском контексту, CAShapeLayer шаље команде директно на GPU преко Metal-а. Резултат — веће перформансе, посебно током анимације.

CAShapeLayer је посебно користан за елементе интерфејса који мењају облик као одговор на радње корисника: индикатори напретка, графикони, иконе таб-бара, маске за анимацију појављивања садржаја.

Како CAShapeLayer рендерује контуру на GPU-у

Процес рендеровања CAShapeLayer-а се разликује од основног CALayer-а. Уместо чувања растерског бафера са пикселима, CAShapeLayer шаље GPU-у опис темена контуре — скуп тачака, Безијеових кривих и сегмената. GPU растеризује ову контуру у једном пролазу, примењујући боју попуне и контуре у фази фрагментног шејдера.

Овај приступ даје две предности: скалирање без губитка квалитета (векторска графика остаје оштра при било којој резолуцији) и ефикасну анимацију — при промени path GPU прерачунава само измењене пикселе, не цео екран.

Основна својства CAShapeLayer-а

path — централно својство CAShapeLayer-а, које прима CGPath. Контура може садржати линије, лукове, Безијеове криве и правоугаонике. Креира се кроз UIBezierPath у Swift-у или CGPath у Core Graphics-у. Пример: UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPath креира заобљени правоугаоник.

  • fillColor — боја попуне затворене контуре (CGColor). Ако је nil — без попуне. Подржава анимацију.
  • strokeColor — боја контуре. Анимира се заједно са lineWidth, стварајући ефекат исцртавања контуре.
  • lineWidth — дебљина линије контуре у тачкама. Подразумевано 1.0. Може се анимирати.
  • lineCap — стил завршетка линије: .butt (равни рез), .round (заобљен), .square (правоугаони са испустом).
  • lineJoin — стил спајања линија: .miter (оштар угао), .round (заобљен), .bevel (одсечен).
  • strokeStart и strokeEnd — удео исцртане контуре од 0.0 до 1.0. Анимација strokeEnd ствара ефекат постепеног појављивања.
  • fillRule — правило попуне контура које се укрштају: .nonZero (подразумевано) или .evenOdd.
  • miterLimit — максимална дужина врха при lineJoin = .miter. Спречава бесконачно дуге углове.

Својство lineDashPattern омогућава креирање испрекиданих линија. Прима низ бројева: [6, 3] значи 6 тачака црте и 3 тачке размака. lineDashPhase поставља померај шаблона и може се анимирати за ефекат покретне испрекидане линије.

CAShapeLayer vs CALayer: када изабрати који

Избор између CAShapeLayer и основног CALayer-а зависи од типа садржаја. Ако је елемент правоугаона област са позадином, границом и сенком — довољан је CALayer. Ако елемент има произвољан облик, захтева анимацију контуре или скалирање без губитка квалитета — CAShapeLayer је пожељнији.

Перформансе се такође разликују. CALayer са cornerRadius и masksToBounds ствара offscreen бафер за обрезивање садржаја, што додаје 2–5 ms по кадру. CAShapeLayer не захтева offscreen бафер — обрезивање се врши на нивоу теменог шејдера. За елементе са сложеном маском, CAShapeLayer може бити 2–3 пута бржи.

  • CALayer: правоугаони елементи, фотографије, видео, садржај са заобљеним угловима (cornerRadius), сенке, границе.
  • CAShapeLayer: иконе, графикони, траке напретка, маске произвољног облика, анимиране контуре, облици за анимацију појављивања.
  • CATextLayer: текст који захтева субпикселно рендеровање и кеширање глифова.
  • CAGradientLayer: градијентна попуна — комбинује се са CAShapeLayer кроз mask за креирање облика са градијентом.

Комбиновање CAShapeLayer-а са другим слојевима је уобичајен образац. На пример, CAGradientLayer користи CAShapeLayer као маску за креирање облика са градијентном попуном. Овај приступ даје и векторски квалитет и градијентну попуну без губитка перформанси.

Анимација CAShapeLayer-а: path и stroke

Анимација path — једна од најмоћнијих могућности CAShapeLayer-а. Ако обе контуре (почетна и крајња) имају исти број контролних тачака и сегмената, Core Animation врши глатку интерполацију између њих. Резултат — ефекат морфинга једног облика у други.

Услов компатибилности path: почетни и крајњи UIBezierPath морају имати исту структуру — број позива moveTo, addLine, addCurve и addQuadCurve мора да се поклапа. Ако се структура разликује, анимација ће бити тренутна, без интерполације.

Према Apple WWDC 2024, комбинација strokeStart и strokeEnd је најчешће коришћени образац анимације CAShapeLayer-а. Анимација strokeEnd од 0.0 до 1.0 ствара ефекат цртања контуре од почетка до краја. Користи се у индикаторима учитавања, анимацијама појављивања графикона и прилагођеним транзицијама између екрана.

За стварање ефекта пулсирања, анимирај истовремено strokeEnd и opacity са различитим timing функцијама. За ефекат покретне испрекидане линије, анимирај lineDashPhase уз фиксни lineDashPattern. Оба трика се реализују кроз CABasicAnimation без учешћа CPU-а.

Анимација као маска

CAShapeLayer се често користи као mask за друге слојеве. На пример, за анимацију појављивања садржаја: на почетку mask.path је правоугаоник нулте величине, крајњи — пуна величина. Core Animation интерполира path, и садржај се открива глатко.

Овај образац се користи у iOS-у за анимацију размотавања картица, појављивања модалних прозора и транзиција између view controller-а. За разлику од анимације alpha, анимација кроз маску CAShapeLayer-а даје природнији ефекат појављивања са произвољним обликом.

Примери кода са CAShapeLayer у Swift-у

Први пример — креирање кружног индикатора напретка са анимацијом strokeEnd. Ово је стандардни UI елемент који демонстрира основне могућности CAShapeLayer-а:

swift
func createProgressIndicator(in view: UIView) -> CAShapeLayer {
    let circlePath = UIBezierPath(
        arcCenter: CGPoint(x: 50, y: 50),
        radius: 40,
        startAngle: -.pi / 2,
        endAngle: 3 * .pi / 2,
        clockwise: true
    )

    let trackLayer = CAShapeLayer()
    trackLayer.path = circlePath.cgPath
    trackLayer.strokeColor = UIColor.systemGray5.cgColor
    trackLayer.fillColor = nil
    trackLayer.lineWidth = 8
    view.layer.addSublayer(trackLayer)

    let progressLayer = CAShapeLayer()
    progressLayer.path = circlePath.cgPath
    progressLayer.strokeColor = UIColor.systemBlue.cgColor
    progressLayer.fillColor = nil
    progressLayer.lineWidth = 8
    progressLayer.lineCap = .round
    progressLayer.strokeEnd = 0
    view.layer.addSublayer(progressLayer)

    return progressLayer
}

// Анимирај до 75%
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

Други пример — анимација морфинга између круга и квадрата. Оба UIBezierPath имају компатибилну структуру:

swift
let morphLayer = CAShapeLayer()
morphLayer.fillColor = UIColor.systemPurple.cgColor
morphLayer.frame = rect

let circlePath = UIBezierPath(roundedRect: rect, cornerRadius: rect.width / 2)
let squarePath = UIBezierPath(roundedRect: rect, cornerRadius: 0)
morphLayer.path = circlePath.cgPath

let morphAnimation = CABasicAnimation(keyPath: "path")
morphAnimation.toValue = squarePath.cgPath
morphAnimation.duration = 0.6
morphAnimation.autoreverses = true
morphAnimation.repeatCount = .infinity
morphLayer.add(morphAnimation, forKey: "morph")

Трећи пример — маска са CAShapeLayer-ом за анимацију појављивања садржаја. Маска се шири од центра ка ивицама:

swift
func revealContent(_ view: UIView) {
    let maskLayer = CAShapeLayer()
    let size = view.bounds.size.width * 1.5
    let center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)

    let initialPath = UIBezierPath(arcCenter: center, radius: 0, startAngle: 0, endAngle: .pi * 2, clockwise: true)
    let finalPath = UIBezierPath(arcCenter: center, radius: size, startAngle: 0, endAngle: .pi * 2, clockwise: true)

    maskLayer.path = initialPath.cgPath
    view.layer.mask = maskLayer

    let animation = CABasicAnimation(keyPath: "path")
    animation.toValue = finalPath.cgPath
    animation.duration = 0.4
    animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
    maskLayer.add(animation, forKey: "reveal")
    maskLayer.path = finalPath.cgPath
}

Често постављана питања

По чему се CAShapeLayer разликује од цртања у drawRect-у?

drawRect користи CPU за рендеровање у растерском контексту — споро је за анимације. CAShapeLayer рендерује контуру на GPU-у, што даје 60 FPS при анимацији path, strokeEnd и трансформација. Поред тога, CAShapeLayer не захтева прецртавање при промени величине — облик се скалира векторски.

Зашто анимација path не ради глатко?

Глатка анимација path захтева исту структуру почетног и крајњег UIBezierPath-а. Број позива moveTo, addLine, addCurve мора да се поклапа. Користи UIBezierPath са истим бројем сегмената за почетни и крајњи облик.

Како креирати испрекидану линију у CAShapeLayer-у?

Постави lineDashPattern — низ бројева који наизменично одређују дужину црте и размака. На пример, [8, 4] ствара црте од 8pt са размацима од 4pt. За покретну испрекидану линију, анимирај lineDashPhase кроз CABasicAnimation са линеарном timing функцијом.

Може ли се CAShapeLayer користити као маска?

Да, ово је један од основних сценарија. Додели CAShapeLayer својству mask било ког CALayer-а, укључујући CAGradientLayer и друге подкласе. Анимација path маске ствара ефекат глатког појављивања садржаја кроз облик произвољне форме.

Како попунити облик градијентом кроз CAShapeLayer?

Креирај CAGradientLayer и постави његов mask = CAShapeLayer са жељеним path-ем. Градијент ће бити видљив само унутар контуре маске. Овај образац комбинује предности векторског облика CAShapeLayer-а и градијентне попуне CAGradientLayer-а.

Резиме

  • CAShapeLayer — подкласа CALayer-а за хардверско рендеровање векторских контура на GPU-у кроз CGPath.
  • Кључна својства: path, fillColor, strokeColor, lineWidth, lineCap, lineJoin, strokeStart, strokeEnd.
  • Анимација path ствара морфинг облика — захтева исту структуру почетне и крајње контуре.
  • Анимација strokeEnd — стандардни образац за индикаторе напретка и исцртавање контура.
  • CAShapeLayer не захтева offscreen бафер за маскирање, за разлику од CALayer-а са masksToBounds.
  • Користи се као маска за CAGradientLayer, стварајући облике са градијентном попуном.
  • За испрекидане линије користи lineDashPattern са анимацијом lineDashPhase за ефекат покрета.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође