CGGradient هو كائن في Core Graphics يمثل انتقالاً سلساً بين لونين أو أكثر. على عكس رسم التدرج عبر حلقة مع تغيير اللون، يستخدم CGGradient حسابات مسرّعة بالأجهزة ويدعم نوعين: خطي (محوري) وشعاعي. وفقاً لوثائق Apple (2026)، يُستخدم CGGradient لإنشاء تعبئات واقعية وتأثيرات خلفية ومحاكاة مصادر الضوء في واجهات iOS وmacOS.
النقاط الرئيسية
CGGradient هو كائن غير قابل للتغيير في Core Graphics يغلف مجموعة من الألوان وقواعد مزجها على طول انتقال التدرج. داخلياً، يخزن CGGradient مصفوفة من CGColor ومصفوفة من المواضع (locations) في النطاق [0.0, 1.0] ومرجعاً إلى CGColorSpace الذي يتم تفسير الألوان فيه. يرتبط كل لون بموضع على مقياس التدرج: الموضع 0.0 يتوافق مع البداية، و1.0 مع نهاية الانتقال.
عند إنشاء CGGradient باستخدام الدالة CGGradientCreateWithColors، تقوم Core Graphics بحساب القيم اللونية الوسيطة مسبقاً. يمكن أن يحتوي التدرج على عدد عشوائي من نقاط التوقف اللونية (color stops)، مما يسمح بانتقالات معقدة متعددة الألوان. يجب أن يكون عدد الألوان اثنين على الأقل، ويجب أن يتوافق كل لون مع موضع في مصفوفة locations.
تختلف بنية CGGradient عن واجهات برمجة التطبيقات عالية المستوى مثل CAGradientLayer من Core Animation في أنها تعمل مباشرة في سياق Core Graphics. وهذا يوفر تحكماً كاملاً في عملية الرسم والقدرة على دمج التدرجات مع عمليات Quartz 2D الأخرى — أقنعة القص والظلال والتحويلات.
Core Graphics يدعم نوعين من التدرجات: خطي (محوري) وشعاعي. يتم إنشاء التدرج الخطي باستخدام الدالة CGGradientCreateWithColors ويتم رسمه باستخدام CGContextDrawLinearGradient. يتطلب التدرج الشعاعي نفس بنية CGGradient ولكن يتم رسمه باستخدام CGContextDrawRadialGradient.
| النوع | دالة الرسم | المعلمات | الاستخدام |
|---|---|---|---|
| خطي | CGContextDrawLinearGradient | startPoint, endPoint, options | خلفيات، أزرار، أشرطة تقدم |
| شعاعي | CGContextDrawRadialGradient | startCenter, startRadius, endCenter, endRadius, options | إضاءات، مصادر ضوء، ظلال |
التدرج الخطي يمتد انتقال اللون على طول خط مستقيم من نقطة البداية startPoint إلى نقطة النهاية endPoint. يتم استيفاء الألوان بين هاتين النقطتين، ويتم التحكم في السلوك خارج حدودهما بواسطة خيارات التمديد. التدرج الخطي مثالي لإنشاء خلفيات ناعمة ومحاكاة الأسطح المعدنية وانتقالات الألوان في عناصر الواجهة.
التدرج الشعاعي ينشئ انتقالاً لونياً من دائرة إلى أخرى. يتم تعريف كل دائرة بمركز (startCenter / endCenter) ونصف قطر (startRadius / endRadius). يتم استيفاء اللون من الدائرة الداخلية إلى الخارجية. حالة خاصة هي عندما يكون نصف القطر الأولي 0: ينتشر التدرج من نقطة واحدة. تُستخدم التدرجات الشعاعية لمحاكاة مصادر الضوء والعدسات والأجرام السماوية وتأثيرات تسليط الضوء.
CGGradient يتم إنشاؤه بدالة أساسية واحدة فقط — CGGradientCreateWithColors. تأخذ الدالة CGColorSpace ومصفوفة من CGColor (CFArray) ومصفوفة من CGFloat locations. إذا كانت locations تساوي NULL، يتم توزيع الألوان بالتساوي على طول مقياس التدرج. إذا تم تحديد locations، يجب أن يتطابق عددها مع عدد الألوان.
مصفوفة locations تحتوي على قيم من 0.0 إلى 1.0 تحدد نقاط التوقف لكل لون. يجب أن تزيد القيم بشكل رتيب. إذا كانت القيمة الأولى أكبر من 0.0، يتم استقراء اللون من البداية إلى هذا الموضع من اللون عند الموضع 0.0. وبالمثل للقيمة الأخيرة الأقل من 1.0. يتم التحكم في هذا السلوك بواسطة خيارات التمديد أثناء الرسم.
عند اختيار الألوان للتدرج، من المهم مراعاة فضاء الألوان. يجب أن تنتمي جميع الألوان في CGGradient واحد إلى نفس CGColorSpace — تقوم Core Graphics باستيفاء المكونات في ذلك الفضاء. إذا تم إنشاء الألوان في فضاءات مختلفة، يجب تحويلها أولاً إلى فضاء مشترك باستخدام CGColorCreateCopyByMatchingToColorSpace.
Core Graphics يوفر دالتين لرسم التدرج: CGContextDrawLinearGradient للخطي و CGContextDrawRadialGradient للشعاعي. تقبل كلتا الدالتين سياقاً رسومياً وكائن CGGradient وخيارات تمديد ومعلمات هندسية خاصة بالنوع. يتم الرسم مع مراعاة قناع القص الحالي وتحويل السياق.
خيارات التمديد تتحكم في سلوك التدرج خارج نطاق المواضع 0.0–1.0. الثابت kCGGradientDrawsBeforeStartLocation يملأ المنطقة قبل موضع البداية بلون التوقف الأول. kCGGradientDrawsAfterEndLocation يملأ بلون التوقف الأخير. يمكن دمج هذه الخيارات باستخدام قناع بت. بالنسبة للتدرجات الشعاعية، تنطبق الخيارات على المنطقة خارج أنصاف الأقطار الابتدائية والنهائية.
التدرج يُرسَم في نظام إحداثيات السياق الرسومي الحالي، مع مراعاة تحويله (CTM — مصفوفة التحويل الحالية). تطبيق CGContextTranslateCTM أو CGContextScaleCTM أو CGContextRotateCTM قبل استدعاء دالة الرسم يغير موضع التدرج ومقياسه. وهذا يسمح بإعادة استخدام CGGradient واحد لمناطق مختلفة دون إنشاء كائنات جديدة.
Core Graphics يوفر عدة آليات إضافية للتحكم في التدرجات: التنعيم (antialiasing) والإخفاء عبر قناع القص (clipping mask) والدمج مع تأثيرات الشفافية. التنعيم مفعل افتراضياً في السياق الرسومي ويتم التحكم فيه عبر CGContextSetShouldAntialias.
قناع القص يسمح بتقييد منطقة رسم التدرج بشكل عشوائي. قبل استدعاء CGContextDrawLinearGradient، يجب تحديد مسار عبر CGContextBeginPath و CGContextAddPath و CGContextClip. يتم رسم التدرج فقط داخل المنطقة المحددة بهذا المسار. يُستخدم هذا على نطاق واسع لإنشاء أيقونات متدرجة وأزرار وأشرطة تقدم.
تمديد التدرج هو معلمة مهمة أخرى. عند استخدام kCGGradientDrawsBeforeStartLocation، تقوم Core Graphics باستقراء لون التوقف الأول على كامل المنطقة قبل startPoint. بدون هذا الخيار، تبقى المنطقة خارج التدرج غير معبأة (شفافة). يضمن دمج كلا الخيارين ملء مستطيل السياق الرسومي بأكمله بتدرج، حتى لو كان startPoint و endPoint داخل المستطيل.
دعنا نلقي نظرة على أمثلة عملية لإنشاء ورسم التدرجات في iOS باستخدام CGGradient و Core Graphics.
هذا المثال ينشئ تدرجاً خطياً بثلاثة ألوان (أزرق، أخضر، أحمر) ويرسمه قطرياً عبر UIView. مصفوفة locations توزع الألوان بشكل غير متساو: الأزرق من 0.0 إلى 0.3، الأخضر عند 0.6، الأحمر من 0.6 إلى 1.0.
func drawLinearGradient(in ctx: CGContext,
rect: CGRect) {
let colors = [
UIColor.blue.cgColor,
UIColor.green.cgColor,
UIColor.red.cgColor
] as CFArray
let locations: [CGFloat] = [0.0, 0.6, 1.0]
let space = CGColorSpaceCreateDeviceRGB()
guard let gradient = CGGradientCreateWithColors(
space, colors, locations
) else { return }
let start = CGPoint(x: 0, y: 0)
let end = CGPoint(x: rect.width,
y: rect.height)
ctx.drawLinearGradient(gradient,
start: start, end: end,
options: [.drawsBeforeStartLocation,
.drawsAfterEndLocation])
}
هذا المثال يرسم تدرجاً شعاعياً يحاكي تأثير التوهج. نقطة البداية بنصف قطر صفري تحدد مركز التوهج، والدائرة الخارجية تحدد حد التلاشي. يُستخدم هذا التأثير لتسليط الضوء على عناصر الواجهة أو مؤشرات النشاط.
func drawRadialGlow(in ctx: CGContext,
center: CGPoint) {
let colors = [
UIColor.white.cgColor,
UIColor.orange.cgColor,
UIColor.clear.cgColor
] as CFArray
let locations: [CGFloat] = [0.0, 0.4, 1.0]
let gradient = CGGradientCreateWithColors(
CGColorSpaceCreateDeviceRGB(), colors, locations)
ctx.drawRadialGradient(gradient,
startCenter: center, startRadius: 0,
endCenter: center, endRadius: 100,
options: [.drawsBeforeStartLocation,
.drawsAfterEndLocation])
}
في هذا المثال، التدرج مقيد بمنطقة دائرية عبر مسار قص. قبل رسم التدرج، يتم تحديد مسار دائري يصبح قناع السياق الحالي. يملأ التدرج فقط المنطقة داخل الدائرة، مما يخلق تأثير أيقونة متدرجة.
func drawGradientInCircle(in ctx: CGContext,
rect: CGRect) {
// Creating circular clip path
let circlePath = CGMutablePath()
circlePath.addEllipse(in: rect)
ctx.addPath(circlePath)
ctx.clip()
// Drawing gradient inside clip mask
let colors = [UIColor.magenta.cgColor,
UIColor.cyan.cgColor]
let gradient = CGGradientCreateWithColors(
CGColorSpaceCreateDeviceRGB(),
colors as CFArray, nil)
ctx.drawLinearGradient(gradient,
start: CGPoint(x: 0, y: 0),
end: CGPoint(x: rect.width,
y: rect.height),
options: [.drawsBeforeStartLocation])
}
الأسئلة الشائعة
CGGradient هو كائن منخفض المستوى في Core Graphics للرسم في سياق رسومي. CAGradientLayer هو طبقة عالية المستوى من Core Animation مع رسوم متحركة تلقائية وتسريع بالأجهزة. CAGradientLayer أسهل في الاستخدام مع UIKit، لكن CGGradient يوفر تحكماً كاملاً وتوافقاً مع أي CGContext.
الحد الأدنى هو لونان. الحد الأعلى مقيد فقط بالذاكرة المتاحة، حيث يخزن Core Graphics مصفوفة من الألوان وجدول استيفاء محسوب مسبقاً. عملياً، أكثر من 10–15 لوناً في تدرج واحد غير ضروري — يصبح الانتقال البصري لا يمكن تمييزه عن الانتقال السلس.
استخدم CGColor بقناة ألفا أقل من 1.0 في مصفوفة الألوان. على سبيل المثال، يتم إنشاء لون مع شفافية كـ UIColor(red: 0, green: 0, blue: 1, alpha: 0.5).cgColor. تقوم Core Graphics باستيفاء قناة ألفا تماماً مثل مكونات اللون، مما يخلق انتقالاً سلساً للشفافية.
نعم، CGGradient هو جزء من Core Graphics، متاح على كلتا المنصتين: iOS و macOS. على macOS، يتم رسم التدرج في أي NSView عبر تجاوز drawRect. جميع الدوال CGGradientCreateWithColors و CGContextDrawLinearGradient و CGContextDrawRadialGradient متطابقة على كلتا المنصتين.
لتدوير تدرج، طبق تحويلاً على السياق الرسومي قبل الرسم: CGContextRotateCTM(ctx, angle). يتم تحديد نقطتي البداية والنهاية للتدرج في نظام الإحداثيات المحلي للسياق بعد التحويل. بدلاً من ذلك، يمكنك حساب إحداثيات النقاط المدورة مباشرة دون تغيير CTM.
الخلاصة
CGContextDrawLinearGradientCGContextDrawRadialGradientسنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.