Custom Font — فایل فونت (TTF, OTF, WOFF2) است که توسعهدهنده برای جایگزینی فونت پیشفرض سیستم به برنامه موبایل اضافه میکند. فونتهای سفارشی برای ایجاد سبک بصری منحصربهفرد، مطابقت با برندبوک و بهبود خوانایی در زبانهای مختلف استفاده میشوند. طبق دادههای Apple Fonts، فونتهای سفارشی در تمام پلتفرمهای اپل پشتیبانی میشوند و Android مکانیزم Font Family را برای سادهسازی بارگذاری فراهم میکند. اتصال صحیح فونت به طور بحرانی بر تایپوگرافی و برداشت کلی از برنامه تأثیر میگذارد.
نکات اصلی
Custom Font (فونت سفارشی) — فایلی با قلم است که در مجموعه استاندارد فونتهای سیستم عامل قرار ندارد. توسعهدهندگان چنین فونتهایی را برای تایپوگرافی منحصربهفرد مطابق با برند به پروژه اضافه میکنند. فونتهای سفارشی میتوانند هم قلمهای تجاری پولی و هم فونتهای رایگان متنباز مانند Inter, Montserrat, Roboto (نسخه سفارشی) باشند.
سناریوهای معمول استفاده از فونتهای سفارشی: لوگوها و عنوانهای برنامههای برند، برنامههای مطالعه با الزامات خاص تایپوگرافی، بازیها با فونتهای موضوعی، برنامههای زبانهای غیرلاتین که فونت سیستم گلیفهای مورد نیاز را پشتیبانی نمیکند. طبق دادههای Google Fonts، بیش از ۶۰٪ از برنامههای Top-100 فونتها را برای تمایز بصری سفارشی میکنند.
فونتهای سیستم (San Francisco در iOS، Roboto در Android) برای رابطها بهینه شدهاند، اما برای تایپوگرافی برند مناسب نیستند. فونت سفارشی شناخت برند را تقویت میکند، میتواند شامل نمادهای خاص (فونتهای آیکون) باشد و خوانایی را برای مخاطبان خاص بهبود بخشد. با این حال استفاده بیش از حد از فونتهای مختلف UX را بدتر میکند — توصیه میشود بیش از ۲-۳ خانواده در هر برنامه نباشد.
پلتفرمهای موبایل چندین فرمت فونت را پشتیبانی میکنند. TrueType (TTF) — رایجترین فرمت، سازگار با تمام نسخههای iOS و Android. OpenType (OTF) — توسعه TTF با پشتیبانی از لیگاتورها، گلیفهای جایگزین و ویژگیهای OpenType. هر دو فرمت دارای پسوند .ttf و .otf هستند و روی پلتفرمهای موبایل یکسان عمل میکنند.
WOFF2 (Web Open Font Format 2) — فرمت فشرده برای وب، پشتیبانی شده در Android از نسخه ۱۰. WOFF2 فشردهسازی ۳۰-۵۰٪ نسبت به TTF را فراهم میکند. برای iOS، WOFF2 از طریق Safari پشتیبانی میشود، اما در برنامههای بومی نیاز به تبدیل به TTF/OTF دارد. Variable Fonts (فونتهای متغیر) — فرمت مدرنی که تمام سبکها را در یک فایل ذخیره میکند.
| فرمت | iOS | Android | فشردهسازی | ویژگیها |
|---|---|---|---|---|
| TTF | بله | بله | خیر | فرمت استاندارد، سازگاری گسترده |
| OTF | بله | بله | خیر | ویژگیهای OpenType، لیگاتورها، گلیفهای جایگزین |
| WOFF2 | از طریق Safari | API 29+ | ۳۰-۵۰٪ | فشرده، برای صرفهجویی در اندازه APK |
| Variable | iOS 11+ | API 29+ | زیاد | یک فایل برای همه سبکها |
برای توسعه موبایل توصیه میشود از OTF به عنوان فرمت اصلی استفاده کنید — ویژگیهای OpenType را در همان اندازه TTF پشتیبانی میکند. برای صرفهجویی در فضای APK از فشردهسازی woff2 یا بارگذاری فونتهای درخواستی استفاده کنید.
فرآیند اتصال فونت سفارشی در iOS از دو مرحله تشکیل شده است: اضافه کردن فایل به bundle پروژه و ثبت در Info.plist. فایل فونت در دایرکتوری پروژه (معمولاً Resources/Fonts) قرار میگیرد و در target گنجانده میشود. در Info.plist آرایه UIAppFonts (Fonts provided by application) با نام فایلهای فونت به همراه پسوند اضافه میشود.
پس از ثبت، فونت از طریق UIFont(name:size:) با نام PostScript در دسترس است. نام PostScript را میتوان از طریق UIFont.familyNames و UIFont.fontNames(forFamilyName:) پیدا کرد. اگر نام نادرست باشد، UIFont(name:size:) nil برمیگرداند. برای اشکالزدایی توصیه میشود تمام فونتهای ثبت شده را در اولین راهاندازی روی صفحه نمایش دهید.
چرخه کامل اتصال فونت Montserrat در پروژه iOS به زبان Swift را بررسی میکنیم. فایل Montserrat-Regular.ttf به پروژه اضافه میشود، در Info.plist مشخص میشود، سپس از طریق UIFont بارگذاری و به UILabel اعمال میشود. برای هر سبک (regular, bold, italic) یک فایل جداگانه و یک ورودی جداگانه در Info.plist اضافه میشود.
// ۱. در Info.plist: UIAppFonts → "Montserrat-Regular.ttf"
// ۲. بارگذاری فونت در کد
guard let customFont = UIFont(name: "Montserrat-Regular", size: 16) else {
// بازگشت به فونت سیستم
label.font = UIFont.systemFont(ofSize: 16)
return
}
label.font = customFont
// ۳. استفاده در NSAttributedString
let attributes = [NSAttributedString.Key.font: customFont]
let attributed = NSAttributedString(string: "Text", attributes: attributes)
مدیریت وضعیت عدم بارگذاری فونت (UIFont nil برمیگرداند) الزامی است. به جای کرش برنامه از فونت سیستم به عنوان fallback استفاده کنید. این به ویژه برای فونتهای بارگذاری شده از شبکه یا اضافه شده به ماژولهای اختیاری مهم است.
برای فونتهای بارگیری شده در صورت نیاز از CTFontManagerRegisterGraphicsFont استفاده میشود. این روش فونت را از دادههای موجود در حافظه (Data) ثبت میکند و آن را برای UIFont در دسترس قرار میدهد. پس از استفاده، فونت را میتوان از طریق CTFontManagerUnregisterGraphicsFont لغو ثبت کرد. بارگذاری پویا برای برنامههایی با مجموعه بزرگ فونت که همه یکباره نیاز نیستند مفید است.
در Android فونتهای سفارشی از طریق سیستم منابع res/font اضافه میشوند. فایلهای TTF یا OTF در res/font/ قرار میگیرند، پس از آن منابع XML Font Family برای گروهبندی سبکها ایجاد میشوند. از Android 8.0 (API 26) به بعد، این تنها روش توصیه شده است. برای نسخههای قدیمی از assets و Typeface.createFromAsset استفاده میشود.
XML Font Family تطابق بین سبک (regular, bold, italic) و فایل فونت را توصیف میکند. در نشانهگذاری XML ویژگی android:fontFamily="@font/my_font" به طور خودکار فایل مناسب را هنگام setTypeface با سبک مربوطه انتخاب میکند. این کار تایپوگرافی را ساده میکند — کافی است خانواده را در تم مشخص کنید و Android خودش bold را هنگام فراخوانی setTypeface(textView, Typeface.BOLD) انتخاب میکند.
یک فایل XML در res/font/my_font.xml ایجاد کنید که در آن همه فایلهای فونت برای سبکهای مختلف فهرست شدهاند. هر عنصر دارای ویژگیهای fontStyle (normal/italic) و fontWeight (100-900) است. پس از آن در نشانهگذاری android:fontFamily="@font/my_font" را مشخص کنید. هنگام استفاده از textStyle="bold"، Android به طور خودکار فایل با fontWeight 700 را انتخاب میکند.
<!-- res/font/my_font.xml -->
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
<font
android:fontStyle="normal"
android:fontWeight="400"
app:font="@font/my_font_regular" />
<font
android:fontStyle="normal"
android:fontWeight="700"
app:font="@font/my_font_bold" />
</font-family>
هنگام استفاده از Font Family، روش منبع به طور خودکار فونتها را کش میکند و سبک صحیح را انتخاب میکند. اگر وزن مورد نیاز در خانواده موجود نباشد، Android آن را از نزدیکترین وزن موجود سنتز میکند. برای کنترل دقیق روی فونت از Typeface.create() با مشخص کردن صریح فایل استفاده کنید.
در فریمورکهای چندپلتفرمی اتصال فونتها یکپارچه شده است. Flutter از pubspec.yaml برای مشخص کردن فونتها استفاده میکند: فایلها در پوشه fonts/ پروژه قرار میگیرند، سپس در بخش fonts با ذکر خانواده و سبکها اعلام میشوند. سپس فونت از طریق TextStyle(fontFamily: 'Montserrat') یا در تم برنامه اعمال میشود. Flutter از TTF و OTF پشتیبانی میکند.
React Native از دو رویکرد استفاده میکند: بومی (از طریق Info.plist و res/font) یا از طریق کتابخانههای react-native-vector-icons و @expo-google-fonts. Expo فرآیند را ساده میکند — فونتها از طریق expo-font بارگذاری میشوند: Font.loadAsync({ 'Montserrat': require('./assets/fonts/Montserrat.ttf') }). React Navigation و تمها امکان تنظیم سراسری فونت را فراهم میکنند.
اعلام فونتها در pubspec.yaml و استفاده در تم MaterialApp. فایلهای Montserrat-Regular.ttf و Montserrat-Bold.ttf در fonts/ قرار میگیرند. پس از اعلام، فونت از طریق TextStyle در کل برنامه در دسترس است. Flutter به طور خودکار از فایل bold هنگام fontWeight: FontWeight.bold استفاده میکند.
// pubspec.yaml
flutter:
fonts:
- family: Montserrat
fonts:
- asset: fonts/Montserrat-Regular.ttf
- asset: fonts/Montserrat-Bold.ttf
weight: 700
// استفاده در تم
MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
headlineLarge: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
fontSize: 28
)
)
)
)
اگر Flutter فونت را در مسیر مشخص شده پیدا نکند، برنامه بدون خطا از فونت fallback سیستم استفاده میکند. برای اشکالزدایی checkConsistency را در MaterialApp فعال کنید — وجود فونتها را بررسی میکند و در صورت عدم وجود هشدارهایی در کنسول نمایش میدهد.
اندازه APK و IPA به طور مستقیم به تعداد فونتهای گنجانده شده بستگی دارد. یک فایل TTF برای مجموعه کاراکترهای لاتین ۵۰-۵۰۰ کیلوبایت و برای فونتهای پشتیبان از سیریلیک، نویسههای چینی یا سایر مجموعههای گسترده تا ۲-۵ مگابایت وزن دارد. ده فونت میتوانند ۱۰-۲۰ مگابایت به اندازه برنامه اضافه کنند که برای دانلود موبایل بحرانی است.
برای بهینهسازی از subsetting — حذف کاراکترهای استفاده نشده از فایل فونت استفاده کنید. ابزارهایی مانند glyphhanger, fonttools (pyftsubset) و Google Webfont Optimizer نسخهای از فونت را فقط با گلیفهای مورد نیاز (لاتین + سیریلیک + اعداد + علائم نگارشی) ایجاد میکنند. این اندازه را ۵۰-۸۰٪ کاهش میدهد. در iOS میتوان از منابع درخواستی برای فونتهایی که در اولین راهاندازی نیاز نیستند استفاده کرد.
Variable Font (فونت متغیر) — یک فایل است که تمام سبکها را شامل میشود: از Thin تا Black و از Condensed تا Expanded. یک فونت متغیر میتواند ۱۰-۲۰ فایل جداگانه با وزنهای مختلف را جایگزین کند. اندازه چنین فایلی تقریباً برابر با ۱-۲ فایل استاتیک است. پشتیبانی: iOS 11+, Android 10+, Flutter (از طریق FontVariation), React Native (از طریق کتابخانههای سفارشی).
برای کاهش اندازه فونتها به میزان ۳۰-۵۰٪ از WOFF2 استفاده کنید. در Android با API ۲۹ میتوان مستقیماً از WOFF2 استفاده کرد. برای iOS لازم است WOFF2 قبل از ثبت به TTF تبدیل شود. فونتهایی را که فقط در onboarding یا صفحههای خاص استفاده میشوند از طریق منابع درخواستی (iOS) یا Dynamic Feature (Android) بارگذاری کنید — آنها وارد APK پایه نخواهند شد.
فونتهای سفارشی به دو روش بر عملکرد تأثیر میگذارند: زمان بارگذاری و حافظه. در اولین مراجعه به فونت، سیستم فایل را از دیسک میخواند، جداول فونت را تجزیه میکند و ساختارهای داخلی برای رندرینگ ایجاد میکند. برای فونت ۱ مگابایتی این کار ۲۰-۵۰ میلیثانیه طول میکشد. کش کردن پس از اولین بارگذاری تأخیر را در مراجعات بعدی برطرف میکند.
حافظه: هر فونت بارگذاری شده در کش فرآیند ذخیره میشود. فونتهای سیستم از پیش بارگذاری شدهاند، فونتهای سفارشی در اولین استفاده بارگذاری میشوند. فونت در حافظه حدود ۲-۳ برابر بیشتر از دیسک فضا اشغال میکند، به دلیل ساختارهای تجزیه شده: جداول cmap, glyf, head, hmtx. برای ۵ فونت سفارشی با اندازه متوسط (حجم کل ۳ مگابایت) حدود ۶-۹ مگابایت RAM نیاز است.
تعداد فونتهای سفارشی را به ۲-۳ خانواده در هر برنامه محدود کنید. از فونتهای متغیر برای جایگزینی چندین سبک استفاده کنید. فونتهای سیستم را برای عناصر UI (دکمهها، برچسبها، لیستها) و فونتهای سفارشی را فقط برای تایپوگرافی تاکیدی (عنوانها، بنرها) به کار ببرید. Typeface را در Android از طریق Map و UIFont را در iOS از طریق متغیرهای استاتیک کش کنید.
object FontCache {
private val cache = mutableMapOf<String, Typeface>()
fun get(context: Context, fontId: Int): Typeface {
return cache.getOrPut(fontId.toString()) {
ResourcesCompat.getFont(context, fontId)
}
}
}
// استفاده در RecyclerView
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView.typeface = FontCache.get(context, R.font.montserrat_regular)
}
بارگذاری Typeface در onBindViewHolder فقط در حضور کش مجاز است. بدون کش هر فراخوانی createFromAsset یک شیء جدید ایجاد میکند و فایل را از دیسک میخواند. هنگام اسکرول RecyclerView این باعث لگهای قابل توجه میشود. کش مشکل را حل میکند، زیرا فونت یک بار بارگذاری شده و دوباره استفاده میشود.
سوالات متداول
OTF — انتخاب بهینه برای برنامههای موبایل. ویژگیهای OpenType (لیگاتورها، گلیفهای جایگزین) را در همان اندازه TTF پشتیبانی میکند. برای صرفهجویی در فضا از فونتهای متغیر TTX یا OTF با subsetting استفاده کنید. WOFF2 فقط برای Android 10+ مناسب است و در iOS در برنامههای بومی پشتیبانی نمیشود.
بله. Google Fonts فونتها را تحت مجوز OFL (Open Font License) برای استفاده تجاری فراهم میکند. فونتها را میتوان از fonts.google.com دانلود و به پروژه اضافه کرد. Android از Downloadable Fonts از طریق Google Play Services پشتیبانی میکند که امکان عدم گنجاندن فایلهای فونت در APK و بارگذاری آنها در اولین استفاده را فراهم میکند.
شایعترین دلایل: فایل به target اضافه نشده (iOS)، در Info.plist مشخص نشده (iOS)، فایل در res/font نیست (Android)، نام PostScript نادرست، فایل خراب است. برای تشخیص در iOS UIFont.familyNames را در کنسول نمایش دهید. در Android از FontLoader برای اشکالزدایی بارگذاری فونتها از assets استفاده کنید.
از subsetting (pyftsubset) برای حذف کاراکترهای استفاده نشده استفاده کنید — اندازه را ۵۰-۸۰٪ کاهش میدهد. به جای ۱۰ فایل جداگانه از فونتهای متغیر استفاده کنید. برای Android 10+ از فشردهسازی WOFF2 استفاده کنید. ProGuard را برای مبهمسازی مسیرهای فونت پیکربندی کنید. برای iOS از منابع درخواستی استفاده کنید.
توصیه میشود به ۲-۳ خانواده محدود شوید (شامل سبکهای مختلف). هر خانواده ۲۰۰ کیلوبایت تا ۳ مگابایت به اندازه برنامه اضافه میکند. فونتهای سیستم برنامه را سنگین نمیکنند، بنابراین برای عناصر UI از فونتهای سیستم و فونتهای سفارشی را برای عنوانها و بلوکهای تاکیدی نگه دارید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید