UIFont و CTFont هما فئتان للعمل مع الخطوط في iOS: UIFont من UIKit لإعداد النص عالي المستوى في UILabel و UITextView، CTFont من Core Text للعرض منخفض المستوى مع تحكم كامل في الرموز الرسومية والمقاييس. وفقاً لوثائق Apple Developer، يُستخدم UIFont في 90% من مكونات واجهة المستخدم القياسية، بينما يُستخدم CTFont في محركات النص المخصصة والمحررات. تمثل كلتا الفئتين خطاً واحداً ولكن بمستوى مختلف من التجريد.
النقاط الرئيسية
UIFont هي فئة UIKit تمثل خطاً لعرض النص في مكونات واجهة المستخدم: UILabel و UITextView و UITextField. توفر واجهة بسيطة للحصول على خطوط النظام والخطوط المخصصة مع تحديد الحجم والوزن والنمط. لا يسمح UIFont بالتحكم المباشر في الترقيم والربط وميزات OpenType — لذلك يُستخدم Core Text.
CTFont هو نوع Core Text (CTFontRef) يوفر وصولاً منخفض المستوى لبيانات الخط. يعمل CTFont مباشرة مع Core Graphics للعرض، ويدعم جميع ميزات OpenType و TrueType بما في ذلك الرموز الرسومية البديلة والربط والخطوط المتغيرة. يُستخدم CTFont داخلياً بواسطة UIKit لعرض UIFont، لكنه متاح أيضاً مباشرة للرسم المخصص.
يدعم UIFont و CTFont الجسر الحر — التحويل بين الأنواع دون تكلفة إضافية. تحويل UIFont إلى CTFont أو CTFont إلى UIFont ممكن في Swift و Objective-C. يتيح ذلك استخدام واجهة برمجة التطبيقات عالية المستوى من UIKit للإعداد و Core Text منخفض المستوى للعرض دون نسخ بيانات الخط.
تستخدم كلتا الفئتين UIFontDescriptor (UIKit) / CTFontDescriptor (Core Text) لوصف خصائص الخط: الاسم والحجم والوزن والنمط ومصفوفة التحويل. الواصف هو قاموس سمات يمكن تعديله لإنشاء خطوط جديدة بناءً على الخطوط الموجودة. على سبيل المثال، إضافة traitItalic إلى واصف للحصول على نسخة مائلة من نفس الخط.
UIFont يوفر عدة طرق مصنعية لإنشاء الخطوط. systemFont(ofSize:) يعيد خط النظام San Francisco (iOS) أو Helvetica (الإصدارات الأقدم). boldSystemFont، italicSystemFont — متغيرات بأنماط محددة. preferredFont(forTextStyle:) يعيد خط Dynamic Type للنمط المحدد: .headline، .body، .caption1، .footnote. يتم تحجيم هذه الخطوط تلقائياً عند تغيير إعدادات حجم النص في النظام.
لتحميل الخطوط المخصصة، يُستخدم UIFont(name:size:) مع اسم PostScript للخط. يجب إضافة الخط أولاً إلى Info.plist وتضمينه في حزمة التطبيق. وفقاً لـ Apple، يُنصح باستخدام UIFort لجميع مكونات واجهة المستخدم القياسية والتحول إلى CTFont فقط عند الحاجة إلى عرض مخصص.
Dynamic Type هو نظام خطوط تكيفي تم تقديمه في iOS 7. يختار المستخدم حجم النص المفضل لديه في الإعدادات — من صغير جداً إلى كبير جداً. يعيد UIFont.preferredFont تلقائياً خطاً بالحجم المناسب. للتشغيل الصحيح، يجب أن تحتوي جميع UILabel على adjustsFontForContentSizeCategory = true. Dynamic Type إلزامي للتوافق مع إمكانية الوصول.
UIFontDescriptor يسمح بتعديل سمات الخط دون إنشاء مثيل جديد من الصفر. الطرق addingAttributes(_:)، withSymbolicTraits(_:)، withFamily(_:) تعيد واصفاً جديداً بمعلمات معدلة. هذا مناسب للحصول على متغيرات الخط: إضافة traitBold إلى خط النظام للحصول على نسخة عريضة دون معرفة اسم PostScript.
CTFont (CTFontRef) هو نوع Core Text للعمل منخفض المستوى مع الخطوط. يُنشأ بواسطة CTFontCreateWithName و CTFontCreateWithFontDescriptor و CTFontCreateCopyWithAttributes. كل دالة تعيد خطاً بالواجهة والحجم والسمات الاختيارية المحددة. يُستخدم CTFont في Core Graphics لعرض النص على UIView مخصص عبر drawRect.
يوفر CTFont الوصول إلى مقاييس غير متوفرة في UIFont: CTFontGetGlyphsForCharacters يعيد مصفوفة من الرموز الرسومية لأحرف معينة، CTFontGetAdvancesForGlyphs — عرض كل رمز رسومي، CTFontGetBoundingBox — حدود الرمز الرسومي. هذا ضروري لبناء تخطيطات نص مخصصة: أعمدة، تدوير، التفاف.
CTFontGetAscent و CTFontGetDescent و CTFontGetLeading تعيد المقاييس الرأسية للخط. CTFontGetUnitsPerEm — عدد الوحدات لكل em-square، يُستخدم لحساب النسب. CTFontGetGlyphCount — العدد الإجمالي للرموز الرسومية في الخط. هذه البيانات حاسمة للطباعة المطبعية والتخطيطات المخصصة حيث يتطلب تحديد موضع دقيق لكل حرف.
CTFont يدعم ميزات OpenType: CTFontCopyFeatures يعيد قاموساً للوظائف المتاحة للخط (الربط والأحرف البديلة والترقيق)، CTFontEnableFeature ينشط خياراً محدداً. يتم تكوين الخطوط المتغيرة عبر CTFontCopyVariation و CTFontCreateCopyWithVariation، مما يسمح بتغيير weight و width و slant في نطاق مستمر.
يتم إنشاء UIFont في Swift من خلال إحدى الطرق المصنعية أو التهيئة المباشرة بالاسم. الطريقة الأكثر شيوعاً هي systemFont(ofSize:weight:) لخطوط النظام أو preferredFont(forTextStyle:) لـ Dynamic Type. للخطوط المخصصة، يُستخدم UIFont(name:size:) مع تحديد اسم PostScript.
يقبل UIFont.systemFont(ofSize:weight:) UIFont.Weight — من .ultraLight إلى .black. تعيد هذه الطريقة خط النظام San Francisco بالوزن المقابل. UIFont.monospacedSystemFont، UIFont.monospacedDigitSystemFont يعيدان خطوط أحادية المسافة للكود والأرقام. جميع خطوط النظام تدعم Dynamic Type تلقائياً.
let regularFont = UIFont.systemFont(ofSize: 16, weight: .regular)
let boldFont = UIFont.systemFont(ofSize: 16, weight: .bold)
let headlineFont = UIFont.preferredFont(forTextStyle: .headline)
let monoFont = UIFont.monospacedSystemFont(ofSize: 14, weight: .regular)
label.font = headlineFont
يمكن تعيين كل خط مباشرة لخاصية font في UILabel أو استخدامه في NSAttributedString عبر NSFontAttributeName. يتم تخزين خطوط النظام في ذاكرة التخزين المؤقت بواسطة iOS، لذلك فإن إعادة إنشاء خط النظام لا تسبب أي حمل إضافي.
لاستخدام خط مخصص، أضف ملف TTF أو OTF إلى حزمة المشروع وحدده في Info.plist (UIAppFonts). يمكن العثور على اسم PostScript للخط عبر UIFont.familyNames و UIFont.fontNames(forFamilyName:). بعد التسجيل، يصبح الخط متاحاً عبر UIFont(name:size:) من أي مكان في التطبيق.
// الحصول على جميع أسماء عائلات الخطوط
for family in UIFont.familyNames {
let names = UIFont.fontNames(forFamilyName: family)
print("\(family): \(names)")
}
// تحميل خط مخصص
if let customFont = UIFont(name: "MyCustomFont-Regular", size: 18) {
label.font = customFont
}
إذا تم تحديد اسم الخط بشكل غير صحيح، يعيد UIFont(name:size:) قيمة nil. يُنصح بطباعة جميع أسماء الخطوط المتاحة عبر UIFont.familyNames و UIFont.fontNames(forFamilyName:) أثناء التصحيح للتأكد من تسجيل الخط بشكل صحيح.
تحميل الخطوط المخصصة ممكن بطريقتين: التسجيل الثابت عبر Info.plist (UIAppFonts) والتسجيل الديناميكي عبر CTFontManagerRegisterGraphicsFont. الطريقة الأولى أبسط — الخط متاح فوراً بعد بدء التطبيق. الثانية تُستخدم للخطوط التي يتم تنزيلها من الشبكة أو الموارد عند الطلب.
التسجيل الديناميكي مفيد للموارد عند الطلب: إذا كان التطبيق يحتوي على 20+ خطاً، يمكن استبعادها جميعاً من الحزمة الأولية وتنزيلها عند الاستخدام الأول. يسجل CTFontManagerRegisterFontsForURLs الخطوط من عناوين URL المحددة. بعد التسجيل، يصبح الخط متاحاً عبر UIFont(name:size:) كالمعتاد.
للعرض المخصص عبر Core Text، استخدم CTFontCreateWithName مع اسم PostScript للخط. الفرق مع UIFont هو أنه يمكن إنشاء CTFont بمصفوفة تحويل (CTFontCreateWithNameAndOptions) — لإنشاء خطوط مشوهة: إمالة، تغيير مقياس المحور X، تدوير. هذا غير متاح في UIFont دون استخدام تحويلات أفينية.
// إنشاء CTFont بمصفوفة إمالة
var matrix = CGAffineTransform(a: 1, b: 0, c: 0.2, d: 1, tx: 0, ty: 0)
let ctFont = CTFontCreateWithName(
"Helvetica" as CFString,
24, &matrix)
// استخدام الجسر الحر مع UIFont
let uiFont = ctFont as UIFont
label.font = uiFont
مصفوفة التحويل تسمح بإنشاء متغيرات مائلة بدون ملف خط منفصل. المعامل c (skew) يضيف إمالة للأحرف. تسمح المصفوفة أيضاً بتغيير مقياس الخط أفقياً — لإنشاء متغيرات مضغوطة أو موسعة من نفس الخط.
الفرق الرئيسي بين UIFont و CTFont هو مستوى التجريد. يوفر UIFont واجهة برمجة تطبيقات بسيطة للمهام الشائعة: الحصول على خط النظام، تغيير الحجم، التطبيق على UILabel. يوفر CTFont تحكماً كاملاً في الخط: الوصول إلى الرموز الرسومية والمقاييس وجداول OpenType والمحاور المتغيرة. يعتمد الاختيار على المهمة.
| الخاصية | UIFont | CTFont |
|---|---|---|
| الإطار | UIKit | Core Text |
| الإنشاء | systemFont / preferredFont / initWithName | CTFontCreateWithName / CTFontCreateWithDescriptor |
| الوصول إلى الرموز الرسومية | لا | CTFontGetGlyphsForCharacters |
| ميزات OpenType | محدود (UIFontDescriptor) | وصول كامل |
| الخطوط المتغيرة | عبر UIFontDescriptor | CTFontCopyVariation / CreateCopyWithVariation |
| العرض | تلقائي في مكونات واجهة المستخدم | Core Graphics، مخصص |
لـ 95% من مهام تطوير iOS، UIFont كافٍ. Core Text مع CTFont مبرر عند إنشاء محررات النص ومولدات PDF والكتب ذات التخطيط الطباعي أو التطبيقات ذات العرض المخصص للغات النادرة.
يتطلب العمل مع الخطوط في iOS مراعاة الأداء. يتم تحميل كل خط فريد في الذاكرة عند أول وصول ويستهلك موارد. خطوط النظام San Francisco محملة مسبقاً ولا تسبب حملاً إضافياً. يتم تحميل الخطوط المخصصة من الملف وتخزينها مؤقتاً بواسطة النظام بعد التحميل الأول.
يُنصح <بتحديد عدد الخطوط الفريدة
في التطبيق من 3 إلى 5 عائلات. يشغل كل خط من 50 كيلوبايت إلى 2 ميجابايت في الذاكرة. استخدام أوزان مختلفة من نفس العائلة (regular، bold، medium) أكثر كفاءة من تحميل عدة عائلات مختلفة.يقوم النظام بتخزين مثيلات UIFont التي تم إنشاؤها مؤقتاً، لذلك فإن الاستدعاءات المتكررة لـ UIFont.systemFont(ofSize: 16, weight: .regular) لا تنشئ كائناً جديداً. ومع ذلك، فإن UIFont(name:size:) للخطوط المخصصة لا يتم تخزينه مؤقتاً دائماً — يُنصح بحفظ الخطوط المستخدمة بكثرة في خصائص ثابتة أو NSCache لتجنب إعادة التحميل من الملف.
عند تسجيل الخطوط ديناميكياً عبر CTFontManagerRegisterGraphicsFont، يمكن أن تكون العملية غير متزامنة إذا تم تنزيل ملف الخط من الشبكة. في هذه الحالة، يجب أن يعرض UILabel أو UITextView خط نظام احتياطياً حتى اكتمال التحميل. بعد التسجيل، يصبح الخط متاحاً وتقوم الشاشة بتحديث عرض النص تلقائياً.
الأسئلة الشائعة
نعم، يدعم UIFont و CTFont الجسر الحر. يتم التحويل عن طريق تحويل بسيط: UIFont إلى CTFont أو CTFont إلى UIFont. لا يحدث أي حمل إضافي أو نسخ بيانات — تشير كلتا الفئتين إلى نفس كائن الخط في الذاكرة.
لجميع مكونات واجهة المستخدم، استخدم UIFont. إنه محسّن لـ UIKit ويدعم Dynamic Type ويتم تحجيمه بشكل صحيح عند تغيير إعدادات النظام. CTFont مبرر فقط للعرض المخصص عبر Core Graphics أو عند الحاجة إلى الوصول إلى مقاييس الخط منخفضة المستوى.
استخدم UIFont.familyNames لقائمة العائلات و UIFont.fontNames(forFamilyName:) لأسماء PostScript. قم باستدعاء هذا الكود في وضع التصحيح وابحث عن الخط المطلوب. يحتوي اسم PostScript عادة على اسم العائلة والنمط: «SFProText-Regular»، «HelveticaNeue-Bold».
نعم، من خلال UIFontDescriptor يمكن تكوين المحاور المتغيرة: weight، width، slant. ومع ذلك، فإن واجهة برمجة تطبيقات UIFont للخطوط المتغيرة محدودة مقارنة بـ CTFontCopyVariation. للتحكم الكامل في المحاور المتغيرة، استخدم Core Text و CTFontCreateCopyWithVariation.
أنشئ قاموساً ثابتاً أو NSCache بمفتاح يجمع الاسم والحجم. بالنسبة لخطوط النظام، يخزن iOS المثيلات مؤقتاً تلقائياً، ولكن بالنسبة للخطوط المخصصة التي تم إنشاؤها عبر UIFont(name:size:)، يُنصح بحفظ الكائنات في ذاكرة التخزين المؤقت للتطبيق لتجنب إعادة التحميل من ملف TTF.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا