CGContext — iOS va macOS-da 2D chizish buyruqlarini bajarish üçün Core Graphics-ning asosiy ob’ekti. U grafik kontekstni ifodalaydi va joriy holatni saqlaydi: toʼldirgich rangi, chiziq qalinligi, transformatsiya, kesish maydoni va shriftlar. Barcha chizish operatsiyalari — chiziqlar, toʻrtburchaklar, matn, tasvirlar — CGContext orqali bajariladi. Apple Developer Documentation, 2026-ga koʼra, CGContext Apple ekotizimidagi barcha rastr va vektor grafikasining asosidir.
Asosiy
CGContext — Core Graphics çerçivasidan 2D render buyruqlarini bajarish üçün muhitni ifodalovchi shaffof boʼlmagan tur (opaque type). U holatlar stekini, joriy rang fazosini, koordinata transformatsiyasini va kesish maydonini boshqaradi. CGContext barcha Quartz 2D chizish funksiyalari oʼzaro aloqada boʼladigan yagona ob’ektdir — barcha grafik operatsiyalar u orqali amalga oshadi.
CGContext maqsadiga qarab bir necha xil koʻrinishda mavjud: xotirada rastr tasvirlar bilan ishlash üçün bitmap context, PDF hujjatlarni yaratish üçün PDF context, ekranda koʻrsatish üçün window context (UIView tomonidan draw(_:) da taqdim etiladi). iOS dasturchilari koʻpincha draw(_:) metodi ichida UIGraphicsGetCurrentContext() yoki oflayn render üçün UIGraphicsBeginImageContextWithOptions dan olingan kontekst bilan ishlaydi.
Kontekst barcha sozlamalarni holatlar steki orqali qoʼllaydi — dasturchi joriy holatni saqlashi (saveGState), parametrlarni oʻzgartirishi va oldingi holatni tiklashi mumkin (restoreGState). Bu turli elementlar turli ranglar, chiziq qalinliklari va transformatsiyalarni talab qiladigan murakkab sahnalarni renderlashda juda muhimdir. Apple WWDC 2023 ga koʼra, holatlar stekidan toʻgʻri foydalanish kod oʻqiluvchanligini oshiradi va vizual artefaktlarning oldini oladi.
CGContextSaveGState kontekstning joriy holatining nusxasini stekka joylaydi. Bu holat barcha sozlamalarni oʻz ichiga oladi: ranglar, chiziq qalinligi, transformatsiya, soyalar, kesish maydoni, shriftlar. Parametrlar oʻzgartirilgandan soʻng CGContextRestoreGState chaqiruvi kontekstni saqlangan holatga qaytaradi, barcha oraliq oʻzgarishlarni bekor qiladi. Stek iOS da 32 holatgacha saqlashi mumkin.
Turli uslubdagi elementlar guruhini chizishda (masalan, diagrammaning rang-barang sektorlari) holatlar steki har bir parametrni qoʻlda eslab qolish va tiklash zaruratini bartaraf qiladi. saveGState/restoreGState boʼlmasa, dasturchi har bir elementdan soʻng rang, soya va transformatsiyani qayta oʻrnatishi kerak boʼladi. Stekdan foydalanish kodni qisqartiradi va tiklash xatolarini bartaraf qiladi.
Saqlash va tiklash muvozanatini saqlash muhim — har bir saveGState uchun mos restoreGState boʻlishi kerak. Muvozanatning buzilishi holatlarning sizib ketishiga yoki muddatidan oldin tiklanishiga olib keladi, bu esa kutilmagan koʻrsatishga sabab boʼladi. Xcode statik analizatori CGContext stek muvozanatini tekshirmaydi, shuning uchun toʻgʻrilik uchun javobgarlik dasturchi zimmasida. Juftliklarni do/finally bloklarida guruhlash tavsiya etiladi.
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 keyingi operatsiyalar üçün toʼldirgich rangini oʻrnatadi. Rang CGColorRef sifatida uzatiladi, tarkibida rang fazosi va rang komponentlari haqida maʼlumot saqlaydi. CGContextSetStrokeColorWithColor kontur rangi üçün xuddi shunday ishlaydi. Apple tez-tez ishlatiladigan CGColorRef larni keshga olishni tavsiya qiladi.
CGContextDrawLinearGradient ikki nuqta orasida belgilangan ranglar bilan chiziqli gradient chizadi. CGContextDrawRadialGradient bir doiradan ikkinchisiga oʻtuvchi radial gradient yaratadi. Gradientlar bilan ishlash üçün avval ranglar va toʻxtash nuqtalari massivini oʻz ichiga olgan CGGradientRef ob’ekti yaratiladi. CGContext dagi gradientlar RGB va Grayscale rang fazolarini qoʼllab-quvvatlaydi.
Hududni gradient bilan toʼldirish oldindan kesish maydonini oʻrnatishni talab qiladi. Clip boʼlmasa, gradient butun kontekstni toʼldiradi, faqat kerakli shaklni emas. Oddiy namuna: kontekstga yoʼl qoʻshish, hududni cheklash üçün clip chaqirish, soʻng gradient chizish. Bu namuna tugmalardan tortib fonlargacha murakkab shakllarning gradient toʼldirilishini talab qiladigan barcha ilovalarda qoʼllaniladi.
| Funksiya | Maqsad | Rang fazosi |
|---|---|---|
| setFillColor | Toʼldirgich rangini oʻrnatadi | Istalgan (CGColor orqali) |
| setStrokeColor | Kontur rangini oʻrnatadi | Istalgan (CGColor orqali) |
| drawLinearGradient | Chiziqli gradient chizadi | RGB yoki Grayscale |
| drawRadialGradient | Radial gradient chizadi | RGB yoki Grayscale |
CGContextAddPath oldindan yaratilgan CGPathRef ni keyingi render üçün kontekstga qoʻshadi. Yoʼl qoʻshilgandan soʻng uni konturlash (strokePath), toʼldirish (fillPath) yoki ikkala operatsiyani ham bajarish mumkin. CGContextBeginPath oldingi yoʼlni tozalab, yangi yoʼlni boshlaydi. Kontekst har bir vaqtda faqat bitta faol yoʼlni qoʼllab-quvvatlaydi.
CGContextMoveToPoint yoʼlning joriy nuqtasini belgilangan koordinatalarga koʻchiradi. CGContextAddLineToPoint joriy nuqtadan berilgan nuqtaga toʻgʻri chiziq chizadi. CGContextAddCurveToPoint kubik Bézier egri chizigʻini qoʻshadi, CGContextAddQuadCurveToPoint — kvadratik. CGContextClosePath oxirgi va birinchi nuqta orasida toʻgʻri chiziq bilan yoʼlni yopadi.
Bu metodlarning barchasi yoʼl ob’ektida chaqiriladigan UIBezierPath dan farqli oʼlaroq, CGContext da ular toʻgʻridan-toʻgʻri kontekstga chaqiriladi. Bu farq yondashuvni tanlashda muhim: UIBezierPath konturlarni qayta ishlatish üçün qulayroq, CGContext — minimal yuklama bilan bir martalik render üçün. CGContext shuningdek CGContextSetLineDash orqali kesik chiziqlarni, CGContextSetLineCap orqali egiluvchan uchlar va CGContextSetLineJoin orqali ulanishlarni qoʼllab-quvvatlaydi.
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 chizish maydonini joriy yoʼl bilan cheklaydi. Barcha keyingi chizish operatsiyalari faqat shu maydon ichida koʻrinadi. Bu maskalash, burchaklarni yumaloqlashtirish va elementlarning nostandart chegaralarini yaratish üçün asosiy mexanizmdir. Kesish maydoni saveGState/restoreGState orqali saqlanadi va tiklanadi.
CGContextTranslateCTM kontekstning koordinata boshini siljitadi. CGContextScaleCTM X va Y oʼlarini masshtablaydi. CGContextRotateCTM koordinata tizimini joriy boshlanish atrofida aylantiradi. Transformatsiyalar yigʻiladi — har bir keyingisi joriy koordinata tizimiga nisbatan qoʼllaniladi. Murakkab transformatsiyalar (siljish + aylanish + masshtab) animatsiya va elementlarni joylashtirish üçün ishlatiladi.
Kesish va transformatsiyani birgalikda ishlatish kuchli imkoniyatlar beradi: kesish orqali murakkab maska chizish, soʻng butun tarkibga transformatsiya qoʼllash mumkin. Oddiy misol — yumaloq qirrali rasmning bir qismini burchak ostida koʻrsatish. Operatsiyalar tartibi muhim: avval kesish maydonini oʻrnating, soʻng transformatsiyani qoʼllang, keyin tarkibni chizing. Apple render siklida CTM (Current Transformation Matrix) oʻzgarishlari sonini minimallashtirishni tavsiya qiladi.
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
// kesish maydoni — doira
ctx.addEllipse(in: CGRect(x: 50, y: 50, width: 200, height: 200))
ctx.clip()
// tarkib transformatsiyasi
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 yordamida gradient diagrammasini yaratishning toʼliq namunasini koʻrib chiqamiz. Diagramma üçta turli rangdagi gradient toʼldirilgan sektor va matn yorliqlarini oʻz ichiga oladi. Kod bir kontekstda saveGState, clip, gradientlar va matn renderining kombinatsiyasini namoyish etadi.
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()
// matn yorligʻi
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
}
}
}
Ushbu misolda diagrammaning har bir sektori oʻz saveGState/restoreGState blokida chiziladi. Bunday yondashuv bir sektorning rang va yoʼl sozlamalari boshqalarga taʼsir qilmasligini kafolatlaydi. addArc metodi boshlangʻich va tugash burchagi orasida yoy yaratadi, closePath sektorni markazga yopadi. Matn yorligʻi sektor burchagining oʼrta chizigʻiga joylashtiriladi, pozitsiyani hisoblash üçün cos va sin trigonometrik funksiyalaridan foydalaniladi.
Tez-tez qayta chizishda ish faoliyatini oshirish üçün burchaklar va pozitsiyalar hisob-kitoblarini alohida massivda keshga olish tavsiya etiladi. CGContext barcha operatsiyalarni CPU da bajaradi, shuning üçün oʻnlab sektorli murakkab sahnalar optimizatsiyani talab qilishi mumkin — masalan, CGLayer da oldindan rastrlash yoki GPU tezlashtirish üçün Metal dan foydalanish. 5–10 elementli koʻpgina UI vazifalari üçün CGContext ish faoliyati maqbuldir.
Tez-tez soʻraladigan savollar
UIView ning draw(_:) metodi ichida yoki UIGraphicsBeginImageContextWithOptions bloki ichida UIGraphicsGetCurrentContext() ni chaqiring. CALayer qatlamlari üçün tayyor kontekstni oladigan CALayerDelegate ning draw(in:) metodidan foydalaning.
fillPath joriy yoʼlning ichki maydonini setFillColor rangi bilan toʼldiradi. strokePath setStrokeColor, setLineWidth va setLineCap parametrlari bilan yoʼl boʼyicha chiziq chizadi. Ikkala operatsiya ketma-ket bajariladi: avval fill, soʻng kerak boʼlsa stroke.
Bitmap CGContext — CGBitmapContextCreate orqali yaratilgan va ekran oʻrniga xotira buferiga chizadigan kontekst. Fon tasvir generatsiyasi, koʻrsatmasdan grafik qayta ishlash va Metal yoki OpenGL üçün tekstura yaratish üçün ishlatiladi.
Core Graphics barcha sozlamalarni tiklash üçün metodni taqdim etmaydi. Oʻzgarishlardan oldin saveGState va boshlangʻich holatga qaytish üçün restoreGState dan foydalaning. Shu bilan birga, xuddi shu parametrlar bilan yangi kontekst yaratishingiz mumkin.
drawLinearGradient chaqirishdan oldin kerakli yoʻlda clip orqali kesish maydonini oʻrnating. Clip boʼlmasa, gradient butun kontekstni toʼldiradi. Tartib: addPath → clip → drawLinearGradient — shakl ichida gradientni kafolatlaydi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.