CGContext — iOS və macOS-da 2D çəkmə əmrlərini yerinə yetirmək üçün Core Graphics-in əsas obyekti. O, qrafik konteksti təmsil edir və cari vəziyyəti saxlayır: dolğu rəngi, xətt qalınlığını, transformasiyanı, kəsmə sahəsini və şriftləri. Bütün çəkmə əməliyyatları — xətlər, dördbucaqlılar, mətn, şəkillər — CGContext vasitəsilə yerinƏ yetirilir. Apple Developer Documentation, 2026-ya görə, CGContext Apple ekosistemində bütün raster və vektor qrafikasının təməlidir.
Başlıca
CGContext — Core Graphics çərçivəsindən 2D render əmrlərini yerinƏ yetirmək üçün mühiti təmsil edən qeyri-şəffaf tip (opaque type). O, vəziyyətlər yığınını, cari rəng məkanını, koordinat transformasiyasını və kəsmə sahəsini idarə edir. CGContext bütün Quartz 2D çəkmə funksiyalarının qarşılıqlı əlaqədə olduğu yeganƏ obyektdir — bütün qrafik əməliyyatları onun vasitƏsilƏ keçir.
CGContext təyinatından asılı olaraq bir neçe növdƏ olur: yaddaşda raster şəkillƏrlƏ işləmək üçün bitmap context, PDF sənƏdləri yaratmaq üçün PDF context, ekranda göstərmək üçün window context (UIView tərƏfindən draw(_:) də təmin edilir). iOS proqramçıları ən çox draw(_:) metodu daxilindƏ UIGraphicsGetCurrentContext() vƏ ya oflayn render üçün UIGraphicsBeginImageContextWithOptions-dan əldə edilən kontekstlƏ işləyirlƏr.
Kontekst bütün parametrlƏri vəziyyətlər yığını vasitƏsilƏ tətbiq edir — proqramçı cari vəziyyəti saxlaya (saveGState), parametrləri dəyişə vƏ əvvəlki vəziyyəti bərpa edƏ bilər (restoreGState). Bu, mürəkkƏb səhnƏlƏri render edərkən kritik əhəmiyyət daşıyır, çünki müxtəlif elementlər müxtəlif rəng, xətt qalınlığı və transformasiya tələb edir. Apple WWDC 2023-Ə görə, vəziyyətlər yığınının düzgün istifadəsi kodun oxunaqlılığını artırır və vizual artefaktların qarşısını alır.
CGContextSaveGState kontekstin cari vəziyyətinin surətini yığına yerləşdirir. Bu vəziyyət bütün parametrləri əhatə edir: rənglər, xətt qalınlığı, transformasiya, kölgƏlər, kəsmə sahəsi, şriftlər. Parametrlər dəyişdirildikdƏn sonra CGContextRestoreGState çağırışı konteksti saxlanılmış vəziyyətə qaytararaq bütün aralıq dəyişiklikləri ləğv edir. Yığın iOS-da 32 vəziyyətə qədər saxlaya bilər.
Müxtəlif üslublu elementlər qrupunu çəkərkən (məsəlƏn, diaqramın çoxrəngli sektorları) vəziyyətlər yığını hər bir parametri əl ilƏ yadda saxlamaq və bərpa etmək zərurətini aradan qaldırır. saveGState/restoreGState olmadan proqramçı hər elementdən sonra rəngi, kölgƏni və transformasiyanı yenidƏ təyin etməli olardı. Yığının istifadəsi kodu qısaltır və bərpa xətalarını aradan qaldırır.
Saxlama və bərpa balansını qorumaq vacibdir — hər saveGState üçün bir restoreGState olmalıdır. Balansın pozulması vəziyyətlərin sızmasına və ya vaxtından ƏvvƏl bərpaya səbəb olur, bu da gözlənilməz göstərimƏ gətirib çıxarır. Xcode statik analizatoru CGContext yığın balansını yoxlamır, buna görƏ düzgünlük məsuliyyəti proqramçının üzərinə düşür. CütlƏri do/finally bloklarında qruplaşdırmaq tövsiyə olunur.
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
ctx.setStrokeColor(UIColor.red.cgColor)
ctx.setLineWidth(3)
ctx.addRect(CGRect(x: 50, y: 50, width: 200, height: 100))
ctx.strokePath()
ctx.restoreGState()
}
CGContextSetFillColorWithColor sonrakı əməliyyatlar üçün dolğu rəngini təyin edir. Rəng CGColorRef kimi ötürülür, tərkibindƏ rəng məkanı və rəng komponentləri haqqında məlumat saxlayır. CGContextSetStrokeColorWithColor kontur rəngi üçün eyni şəkildƏ işləyir. Apple tez-tez istifadə olunan CGColorRef-lərin keşlɘnmɘsini tövsiyə edir.
CGContextDrawLinearGradient iki nöqtə arasında müəyyən edilmiş rənglƏrlƏ xətti gradient çəkir. CGContextDrawRadialGradient bir dairƏdən digərinə keçən radial gradient yaradır. GradientlƏrlƏ işləmək üçün ƏvvƏl rənglər və dayanma nöqtələri massivini ehtiva edən CGGradientRef obyekti yaradılır. CGContext-də gradientlər həm RGB, həm də Grayscale rəng məkanlarını dəstəkləyir.
Sahəni gradientlƏ doldurmaq üçün ƏvvƏlcədən kəsmə sahəsinin təyin edilməsi tələb olunur. Clip olmadan gradient bütün konteksti doldurar, yalnız lazım olan formanı yox. Tipik naxş: kontekstə yol Əlavə etmək, sahəni məhdudlaşdırmaq üçün clip çağırmaq, sonra gradient çəkmək. Bu naxış düymƏlərdƏn fonlara qədər mürəkkƏb formaların gradient dolğusunu tələb edən bütün tətbiqlərdə istifadə olunur.
| Funksiya | Təyinat | Rəng məkanı |
|---|---|---|
| setFillColor | Dolğu rəngini təyin edir | Istənilən (CGColor vasitəsilə) |
| setStrokeColor | Kontur rəngini təyin edir | Istənilən (CGColor vasitəsilə) |
| drawLinearGradient | Xətti gradient çəkir | RGB və ya Grayscale |
| drawRadialGradient | Radial gradient çəkir | RGB və ya Grayscale |
CGContextAddPath sonrakı render üçün ƏvvƏl yaradılmış CGPathRef-i kontekstə Əlavə edir. Yol Əlavə edildikdƏn sonra onu konturlamaq (strokePath), doldurmaq (fillPath) və ya hər iki əməliyyatı yerinƏ yetirmək olar. CGContextBeginPath Əvvəlki yolu təmizləyƏrək yeni bir yola başlayır. Kontekst hər an yalnız bir aktiv yolu dəstəkləyir.
CGContextMoveToPoint yolun cari nöqtəsini göstərilən koordinatlara köçürür. CGContextAddLineToPoint cari nöqtədən verilən nöqtəyə düz xətt çəkir. CGContextAddCurveToPoint kubik Bézier əyrisi Əlavə edir, CGContextAddQuadCurveToPoint — kvadratik. CGContextClosePath son və ilk nöqtə arasında düz xəttlə yolu bağlayır.
Bütün bu metodların yol obyektindƏ çağırıldığı UIBezierPath-dən fərqli olaraq, CGContext-də onlar birbaşa kontekstə çağırılır. Bu fərq yanaşma seçimindƏ vacibdir: UIBezierPath konturların təkrar istifadəsi üçün daha rahatdır, CGContext — minimal yüklƏ birdəfəlik render üçün. CGContext həmçinin CGContextSetLineDash vasitəsilə kəsik xətləri, CGContextSetLineCap vasitəsilə çevik ucları və CGContextSetLineJoin vasitəsilə birləşmələri dəstəkləyir.
let ctx = UIGraphicsGetCurrentContext()!
ctx.beginPath()
ctx.moveTo(x: 50, y: 100)
ctx.addLineTo(x: 200, y: 100)
ctx.addCurveTo(x1: 250, y1: 50, x2: 300, y2: 150, x3: 350, y3: 100)
ctx.setStrokeColor(UIColor.blue.cgColor)
ctx.setLineWidth(5)
ctx.strokePath()
CGContextClip çəkmə sahəsini cari yolla məhdudlaşdırır. Bütün sonrakı çəkmə əməliyyatları yalnız bu sahə daxilindƏ görünəcəkdir. Bu, maskalama, küncləri yuvarlaqlaşdırma və elementlərin qeyri-standart sərhƏdlərini yaratmaq üçün əsas mexanizmdir. Kəsmə sahəsi həmçinin saveGState/restoreGState vasitəsilƏ saxlanılır və bərpa edilir.
CGContextTranslateCTM kontekstin koordinat başlanğıcını yerdəyişdirir. CGContextScaleCTM X və Y oxlarını miqyaslaşdırır. CGContextRotateCTM koordinat sistemini cari başlanğıc ətrafında fırladır. Transformasiyalar toplanır — hər sonrakısı cari koordinat sisteminə nisbətən tətbiq edilir. MürəkkƏb transformasiyalar (yerdəyişmə + fırlanma + miqyas) animasiya və elementlərin yerləşdirilməsi üçün istifadə olunur.
Kəsmə və transformasiyanın birgƏ istifadəsi güclü imkanlar verir: kəsmə vasitƏsilƏ mürəkkƏb maska çəkmək, sonra bütün məzmuna transformasiya tətbiq etmək olar. Tipik nümunə — yuvarlaq kənarlı şəklin bir hissəsini bucaq altında göstərmək. Əməliyyatların ardıcıllığı vacibdir: ƏvvƏl kəsmə sahəsini təyin edin, sonra transformasiya tətbiq edin, daha sonra məzmunu çəkin. Apple render dövründƏ CTM (Current Transformation Matrix) dəyişikliklərinin sayını minimuma endirməyi tövsiyə edir.
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
// kəsmə bölgəsi — dairə
ctx.addEllipse(in: CGRect(x: 50, y: 50, width: 200, height: 200))
ctx.clip()
// məzmun transformasiyası
ctx.translateBy(x: 150, y: 150)
ctx.rotate(by: .pi / 4)
ctx.translateBy(x: -150, y: -150)
UIImage(named: "photo")?.draw(at: CGPoint(x: 50, y: 50))
ctx.restoreGState()
}
CGContext istifadə edərək gradient diaqramının yaradılmasının tam nümunəsini nəzərdən keçirək. Diaqrama gradient dolğusu və mətn etiketləri olan üç müxtəlif rəngli sektor daxildir. Kod bir kontekstdƏ saveGState, clip, gradientlər və mətn renderinin kombinasiyasını nümayiş etdirir.
class PieChartView: UIView {
private struct Slice {
let color: UIColor
let value: CGFloat
let label: String
}
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
let slices = [
Slice(color: .systemRed, value: 0.4, label: "iOS"),
Slice(color: .systemGreen, value: 0.35, label: "Android"),
Slice(color: .systemBlue, value: 0.25, label: "Other")
]
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = bounds.width * 0.35
var startAngle: CGFloat = -.pi / 2
for slice in slices {
let endAngle = startAngle + .pi * 2 * slice.value
ctx.saveGState()
ctx.moveTo(x: center.x, y: center.y)
ctx.addArc(center: center, radius: radius,
startAngle: startAngle, endAngle: endAngle, clockwise: false)
ctx.closePath()
ctx.setFillColor(slice.color.cgColor)
ctx.fillPath()
// mətn etiketi
let midAngle = startAngle + endAngle / 2
let labelPos = CGPoint(
x: center.x + radius * 0.7 * cos(midAngle),
y: center.y + radius * 0.7 * sin(midAngle)
)
slice.label.draw(at: labelPos, withAttributes: [
.foregroundColor: UIColor.white,
.font: UIFont.boldSystemFont(ofSize: 14)
])
ctx.restoreGState()
startAngle = endAngle
}
}
}
Bu nümunƏdƏ diaqramın hər sektoru öz saveGState/restoreGState blokunda çəkilir. Bu yanaşma bir sektorun rəng və yol parametrlərinin digərlərinə təsir etməməsini təmin edir. addArc metodu başlanğıc və son bucaq arasında qövs yaradır, closePath sektoru mərkəzə bağlayır. Mətn etiketi sektor bucağının orta xəttindƏ yerləşdirilir, mövqe üçün cos və sin triqonometrik funksiyalarından istifadə olunur.
Tez-tez yenidƏ çəkmƏ zamanı performansı artırmaq üçün bucaqların və mövqelərin hesablamalarını ayrıca massivdƏ keşlɘmək tövsiyə olunur. CGContext bütün əməliyyatları CPU-da yerinƏ yetirir, buna görƏ onlarla sektoru olan mürəkkƏb səhnƏlər optimizasiya tələb edə bilər — məsəlƏn, CGLayer-dƏ ilkin rastrlşşdırma və ya GPU sürətləndirilməsi üçün Metal istifadəsi. 5–10 elementi olan əksər UI tapşırıqları üçün CGContext performansı məqbuldur.
Tez-tez verilən suallar
UIView-in draw(_:) metodu daxilindƏ və ya UIGraphicsBeginImageContextWithOptions bloku daxilindƏ UIGraphicsGetCurrentContext() çağırın. CALayer təbəqələri üçün hazır kontekst alan CALayerDelegate-in draw(in:) metodundan istifadə edin.
fillPath cari yolun daxili sahəsini setFillColor rəngi ilƏ doldurur. strokePath setStrokeColor, setLineWidth və setLineCap parametrlƏri ilƏ yol boyunca xətt çəkir. Hər iki əməliyyat ardıcıl yerinƏ yetirilir: ƏvvƏl fill, sonra zərurət olduqda stroke.
Bitmap CGContext — CGBitmapContextCreate vasitƏsilƏ yaradılan və ekran əvəzinƏ yaddaş buferinƏ çəkən kontekst. Fon şəkil generasiyası, göstərmədƏn qrafik emalı və Metal və ya OpenGL üçün tekstur yaratmaq üçün istifadə olunur.
Core Graphics bütün parametrləri sıfırlamaq üçün metod təqdim etmir. DəyişikliklərdƏn ƏvvƏl saveGState, ilkin vəziyyətə qayıtmaq üçün restoreGState istifadə edin. Alternativ olaraq eyni parametrlƏrlƏ yeni kontekst yarada bilərsiniz.
drawLinearGradient çağırmazdan ƏvvƏl lazımı yolda clip vasitƏsilƏ kəsmə sahəsini təyin edin. Clip olmadan gradient bütün konteksti doldurar. Ardıcıllıq: addPath → clip → drawLinearGradient — fiqurun içindƏ gradienti təmin edir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun