CGContext, iOS ve macOS'ta 2D çizim komutlarını yürütmek için Core Graphics'ın ana nesnesidir. Geçerli durumu (dolgu rengi, çizgi kalınlığı, dönüşüm, kırpma alanı ve yazı tipleri) depolayan bir grafik bağlamını temsil eder. Tüm çizim işlemleri — çizgiler, dikdörtgenler, metin, resimler — CGContext aracılığıyla gerçekleştirilir. Apple Developer Documentation, 2026'ya göre CGContext, Apple ekosistemindeki tüm raster ve vektör grafiklerinin temelidir.
Önemli Noktalar
CGContext, 2D render komutlarını yürütmek için bir ortamı temsil eden Core Graphics çerçevesinden opak bir türdür (opaque type). Durum yığınını, geçerli renk uzayını, koordinat dönüşümünü ve kırpma alanını yönetir. CGContext, tüm Quartz 2D çizim işlevlerinin etkileşimde bulunduğu tek nesnedir — herhangi bir grafik işlemi ondan geçer.
CGContext, amacına bağlı olarak birkaç çeşitte bulunur: bitmap context bellekte raster görüntülerle çalışmak için, PDF context PDF belgeleri oluşturmak için, window context ekranda çizim için (UIView tarafından draw(_:) içinde sağlanır). iOS geliştiricileri en sık draw(_:) yöntemi içindeki UIGraphicsGetCurrentContext()'ten veya çevrimdışı render için UIGraphicsBeginImageContextWithOptions'dan alınan bir bağlamla çalışır.
Bağlam, tüm ayarları bir durum yığını aracılığıyla uygular — geliştirici geçerli durumu kaydedebilir (saveGState), parametreleri değiştirebilir ve önceki durumu geri yükleyebilir (restoreGState). Bu, farklı öğelerin farklı renkler, çizgi kalınlıkları ve dönüşümler gerektirdiği karmaşık sahneler çizerken kritik öneme sahiptir. Apple WWDC 2023'e göre, durum yığınının doğru kullanımı kod okunabilirliğini artırır ve görsel yapıları önler.
CGContextSaveGState, geçerli bağlam durumunun bir kopyasını yığına iter. Bu durum, tüm ayarları içerir: renkler, çizgi kalınlığı, dönüşüm, gölgeler, kırpma alanı, yazı tipleri. Parametreleri değiştirdikten sonra CGContextRestoreGState çağrısı, bağlamı kaydedilmiş duruma döndürür ve tüm ara değişiklikleri geri alır. Yığın, iOS'ta 32 duruma kadar tutabilir.
Farklı stillerdeki öğe gruplarını çizerken (örneğin, çok renkli grafik sektörleri), durum yığını her parametreyi manuel olarak hatırlama ve geri yükleme ihtiyacını ortadan kaldırır. saveGState/restoreGState olmadan, geliştiricinin her öğeden sonra rengi, gölgeyi ve dönüşümü sıfırlaması gerekirdi. Yığını kullanmak kodu azaltır ve geri yükleme hatalarını önler.
Kaydetme ve geri yükleme dengesini korumak önemlidir — her saveGState'in eşleşen bir restoreGState'i olmalıdır. Dengeyi bozmak, durum sızıntılarına veya erken geri yüklemeye yol açarak öngörülemeyen render almaya neden olur. Xcode'un statik analizörü CGContext yığın dengesini kontrol etmez, bu nedenle doğruluk geliştiricinin sorumluluğundadır. Çiftlerin do/finally bloklarında gruplandırılması önerilir.
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, sonraki işlemler için dolgu rengini ayarlar. Renk, renk uzayı ve renk bileşenleri hakkında bilgi içeren CGColorRef olarak iletilir. CGContextSetStrokeColorWithColor, kontur rengi için benzer şekilde çalışır. Apple, performansı artırmak için sık kullanılan CGColorRef değerlerinin önbelleğe alınmasını önerir.
CGContextDrawLinearGradient, belirtilen renklerle iki nokta arasında doğrusal bir gradyan çizer. CGContextDrawRadialGradient, bir daireden diğerine geçiş yapan radyal bir gradyan oluşturur. Gradyanlarla çalışmak için önce bir dizi renk ve durak konumu içeren bir CGGradientRef nesnesi oluşturulur. CGContext'teki gradyanlar hem RGB hem de Gri Tonlamalı renk uzaylarını destekler.
Bir alanı gradyanla doldurmak önce bir kırpma alanı ayarlamayı gerektirir. clip olmadan, gradyan yalnızca istenen şekli değil, tüm bağlamı dolduracaktır. Tipik desen: bağlama bir yol ekleyin, alanı sınırlamak için clip çağrısı yapın, ardından gradyanı çizin. Bu desen, düğmelerden arka planlara kadar karmaşık şekillerin gradyan dolgularını gerektiren tüm uygulamalarda kullanılır.
| Fonksiyon | Amaç | Renk Uzayı |
|---|---|---|
| setFillColor | Dolgu rengini ayarlar | Herhangi (CGColor ile) |
| setStrokeColor | Kontur rengini ayarlar | Herhangi (CGColor ile) |
| drawLinearGradient | Doğrusal gradyan çizer | RGB veya Gri Tonlamalı |
| drawRadialGradient | Radyal gradyan çizer | RGB veya Gri Tonlamalı |
CGContextAddPath, sonraki render için önceden oluşturulmuş bir CGPathRef'i bağlama ekler. Bir yol eklendikten sonra konturlanabilir (strokePath), doldurulabilir (fillPath) veya her ikisi de yapılabilir. CGContextBeginPath, önceki yolu temizleyerek yeni bir yol başlatır. Bağlam, aynı anda yalnızca bir aktif yolu destekler.
CGContextMoveToPoint, geçerli kontur noktasını belirtilen koordinatlara taşır. CGContextAddLineToPoint, geçerli noktadan verilen noktaya düz bir çizgi çizer. CGContextAddCurveToPoint kübik bir Bézier eğrisi ekler, CGContextAddQuadCurveToPoint ikinci dereceden bir eğri ekler. CGContextClosePath, son ve ilk nokta arasında düz bir çizgiyle konturu kapatır.
Tüm bu yöntemlerin yol nesnesinde çağrıldığı UIBezierPath'in aksine, CGContext'te doğrudan bağlamda çağrılırlar. Bu fark, yaklaşım seçerken önemlidir: UIBezierPath yolları yeniden kullanmak için daha uygundur, CGContext minimum ek yük ile tek seferlik çizim için daha iyidir. CGContext ayrıca CGContextSetLineDash ile kesikli çizgileri, CGContextSetLineCap ile esnek uçları ve CGContextSetLineJoin ile birleştirmeleri destekler.
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, çizim alanını geçerli yolla sınırlar. Sonraki tüm çizim işlemleri yalnızca bu alan içinde görünür olacaktır. Bu, maskeleme, köşeleri yuvarlama ve özel öğe sınırları oluşturma için temel mekanizmadır. Kırpma alanı ayrıca saveGState/restoreGState ile kaydedilir ve geri yüklenir.
CGContextTranslateCTM, bağlam koordinat sisteminin orijinini kaydırır. CGContextScaleCTM, X ve Y eksenlerini ölçekler. CGContextRotateCTM, koordinat sistemini geçerli orijin etrafında döndürür. Dönüşümler birikir — sonraki her biri geçerli koordinat sistemine göre uygulanır. Bileşik dönüşümler (kaydırma + döndürme + ölçekleme) animasyon ve öğe konumlandırma için kullanılır.
Kırpma ve dönüşümleri birleştirmek güçlü yetenekler sağlar: kırpma yoluyla karmaşık bir maske çizebilir, ardından tüm içeriğe bir dönüşüm uygulayabilirsiniz. Tipik bir örnek, yuvarlak köşeli bir açıyla bir görüntü parçasını görüntülemektir. İşlem sırası önemlidir: önce kırpma alanını ayarlayın, sonra dönüşümü uygulayın, ardından içeriği çizin. Apple, çizim döngüsünde CTM (Geçerli Dönüşüm Matrisi) değişikliklerini en aza indirmeyi önerir.
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else { return }
ctx.saveGState()
// clipping region - circle
ctx.addEllipse(in: CGRect(x: 50, y: 50, width: 200, height: 200))
ctx.clip()
// content transformation
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 kullanarak gradyan bir grafik oluşturmanın tam bir örneğine bakalım. Grafik, gradyan dolgular ve metin etiketleriyle birlikte üç farklı renkte sektör içerir. Kod, tek bir bağlamda saveGState, clip, gradyanlar ve metin render'ının kombinasyonunu gösterir.
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()
// text label
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 örnekte, grafiğin her sektörü kendi saveGState/restoreGState bloğunda çizilir. Bu yaklaşım, bir sektörün renk ve yol ayarlarının diğerlerini etkilememesini garanti eder. addArc yöntemi, başlangıç açısından bitiş açısına bir yay oluşturur ve closePath, sektörü merkeze doğru kapatır. Etiket metni, konum hesaplaması için trigonometrik fonksiyonlar cos ve sin kullanılarak sektörün orta açısına yerleştirilir.
Sık yeniden çizim sırasında performansı artırmak için, açı ve konum hesaplamalarının ayrı bir dizide önbelleğe alınması önerilir. CGContext tüm işlemleri CPU'da yürütür, bu nedenle düzinelerce sektör içeren karmaşık sahneler optimizasyon gerektirebilir — örneğin, CGLayer'da önceden render alma veya GPU hızlandırması için Metal kullanımı. 5–10 öğeli çoğu UI görevi için CGContext performansı kabul edilebilir düzeyde kalır.
Sıkça Sorulan Sorular
UIView'in draw(_:) yöntemi içinde veya UIGraphicsBeginImageContextWithOptions bloğu içinde UIGraphicsGetCurrentContext() çağrısı yapın. CALayer katmanları için, hazır bir bağlam alan CALayerDelegate'in draw(in:) yöntemini kullanın.
fillPath, geçerli yolun iç kısmını setFillColor'daki renkle doldurur. strokePath, setStrokeColor, setLineWidth ve setLineCap parametreleriyle yol boyunca bir çizgi çizer. Her iki işlem sırayla gerçekleştirilir: önce dolgu, sonra gerekirse kontur.
Bitmap CGContext, CGBitmapContextCreate aracılığıyla oluşturulan ve ekran yerine bellek tamponuna çizen bir bağlamdır. Arka plan görüntü oluşturma, görüntüleme olmadan grafik işleme ve Metal veya OpenGL için doku oluşturmada kullanılır.
Core Graphics, tüm ayarları sıfırlamak için bir yöntem sağlamaz. Değişikliklerden önce saveGState ve orijinal duruma dönmek için restoreGState kullanın. Alternatif olarak, aynı parametrelerle yeni bir bağlam oluşturun.
drawLinearGradient'i çağırmadan önce, istenen yolda clip ile kırpma alanını ayarlayın. clip olmadan, gradyan tüm bağlamı doldurur. Sıra: addPath → clip → drawLinearGradient — gradyanı şeklin içinde garanti eder.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun