iOS-da CGContext — bu nima, metodlar va chizish kontekstini qanday boshqarish kerak

Muallif: IT Sectr Nashr etilgan: 2026-07-21 O'qish vaqti: 9 daq

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 — barcha 2D Core Graphics buyruqlari bajariladigan grafik kontekst.
  • setStrokeColor va setFillColor kontekstdagi chiziqlar va toʼldirgichlarning rangini boshqaradi.
  • addPath va drawPath ixtiyoriy CGPath konturlarini chizish imkonini beradi.
  • clip(to:) chizishni maʼlum bir zona bilan cheklash üçün kesish maydonini belgilaydi.
  • saveGState va restoreGState kontekst holatlari stekini saqlaydi va tiklaydi.

CGContext nima?

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.

Holatni boshqarish: saveGState va restoreGState

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.

Stekning amaliy qoʼllanishi

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.

swift
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()
}

Ranglar va toʼldirgichlar

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.

CGContext dagi gradientlar

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.

FunksiyaMaqsadRang fazosi
setFillColorToʼldirgich rangini oʻrnatadiIstalgan (CGColor orqali)
setStrokeColorKontur rangini oʻrnatadiIstalgan (CGColor orqali)
drawLinearGradientChiziqli gradient chizadiRGB yoki Grayscale
drawRadialGradientRadial gradient chizadiRGB yoki Grayscale

Kontur va chiziqlarni chizish

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.

Nuqtalar boʼyicha toʻgʻri chiziqlar va egri chiziqlar

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.

swift
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()

Kesish maydoni va transformatsiyalar

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.

Koordinata transformatsiyasi

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.

swift
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 da chizish namunasi

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.

swift
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

iOS da joriy CGContext ni qanday olish mumkin?

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 va strokePath orasidagi farq nima?

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 nima?

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.

CGContext ning barcha sozlamalarini qanday tiklash mumkin?

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.

Nega gradient shakl ichida koʻrinmaydi?

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

  • CGContext — iOS va macOS da barcha 2D chizish operatsiyalari üçün Core Graphics ning markaziy ob’ekti.
  • saveGState va restoreGState yon taʼsirlarning oldini olib, kontekst holatlar stekini boshqaradi.
  • setFillColor va setStrokeColor CGColorRef orqali toʼldirgich va kontur ranglarini oʻrnatadi.
  • addPath, strokePath, fillPath ixtiyoriy CGPath konturlari bilan ishlaydi.
  • clip maskalar va yumaloqlashtirishlar üçün chizish maydonini joriy yoʼl bilan cheklaydi.
  • translateCTM, scaleCTM, rotateCTM kontekstning koordinata tizimini transformatsiya qiladi.
  • Barcha CGContext operatsiyalari CPU da bajariladi — murakkab grafikalar üçün CGLayer yoki Metal dan foydalaning.

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.

Loyihani muhokama qilish

Shuningdek o'qing