Font Descriptor — je objekt UIFontDescriptor v iOS a NSFontDescriptor v macOS, který zapouzdřuje všechna metadata písma: rodinu, řez, velikost, mezery mezi znaky, řádkování a typografické atributy. Místo přímého vytváření písma přes UIFont(name:size:) vývojář popíše požadované charakteristiky pomocí deskriptoru a systém vybere nejlepší shodu z dostupných písem. Podle Apple Developer Documentation UIFontDescriptor podporuje více než 20 atributů písma a používá se ve všech typografických frameworkech iOS — od UIKit přes Core Text až po SwiftUI.
Hlavní body
Font Descriptor — je objekt, který popisuje charakteristiky písma jako sadu párů klíč-hodnota, nikoli jako konkrétní soubor písma. Místo vytváření písma podle názvu vývojář zadá rodinu, řez, velikost a volitelné atributy a systém vybere nejlepší shodu. Tento přístup je klíčový pro adaptivní typografii: stejný deskriptor může fungovat na různých verzích iOS, kde se sada dostupných písem liší. Podle iOS Human Interface Guidelines je párování písem pomocí deskriptorů doporučeným způsobem práce s dynamickými písmy.
Bez Font Descriptor by vývojář musel kontrolovat dostupnost každého písma podle názvu a ručně určovat záložní varianty. Deskriptor tento proces automatizuje: obsahuje matici kompatibility řezů — normální, tučný, kurzíva, tučná kurzíva — a při absenci přesné shody vrací nejbližší dostupný. Systémové párování funguje na úrovni Core Text a je dostupné jak na iOS, tak na macOS prostřednictvím jednotného NSFontDescriptor API.
Deskriptory se také používají pro vlastní písma — načtená přes Info.plist nebo ručně přidaná. Pokud je písmo zaregistrováno v systému, jeho deskriptor se vytvoří stejně jako pro systémové písmo. Meziplatformová poznámka: koncept deskriptoru existuje také v Androidu přes Typeface.Builder, ale iOS implementace přes UIFontDescriptor poskytuje výrazně více atributů — více než 20 oproti 5 v Androidu.
UIFontDescriptor obsahuje atributy seskupené ve slovníku fontAttributes typu [UIFontDescriptor.AttributeName: Any]. Klíčové atributy zahrnují rodinu písma (family), název (name), velikost (size), řez (traits), matici transformace (matrix), optickou velikost (opticalSize) a styl textu (textStyle). Podle Apple WWDC 2019 Session 227 je používání textových stylů — Dynamic Type — povinné pro aplikace kompatibilní s přístupností.
Atribut traits — je slovník obsahující symbolické charakteristiky: tloušťku (UIFontWeightTrait), kurzívu (UIFontSlantTrait), šířku (UIFontWidthTrait) a další. Tyto hodnoty používá vyhledávač písem pro výběr řezu. Například UIFontWeightTrait s hodnotou 0.0 — normální řez, 0.3 — tučný. Systém automaticky mapuje číselné hodnoty na dostupné varianty písma.
Další atributy zahrnují featureSettings pro funkce OpenType (ligatury, kerning, proporce číslic), visibleName pro zobrazení uživateli, matrix pro afinní transformace písma a cascadeList pro kaskádové seznamy záložních písem. Úplný seznam atributů pokrývá prakticky všechny typografické scénáře v iOS a macOS.
| Atribut | Typ | Popis |
|---|---|---|
| UIFontDescriptorFamily | String | Rodina písma (SF Pro, Helvetica Neue) |
| UIFontDescriptorName | String | Plný název písma (HelveticaNeue-Bold) |
| UIFontDescriptorSize | NSNumber | Velikost písma v bodech |
| UIFontDescriptorMatrix | NSValue | Afinní transformační matice |
| UIFontDescriptorTraits | [String: Any] | Symbolické charakteristiky řezu |
| UIFontDescriptorTextStyle | String | Styl Dynamic Type (headline, body, caption) |
Hlavní způsob práce s Font Descriptor v iOS — vytvoření deskriptoru s následnou generací UIFont. Toto je preferovaný přístup, když potřebujete získat písmo s určitými charakteristikami, aniž byste znali přesný název. Proces se skládá ze dvou kroků: vytvoření UIFontDescriptor pomocí inicializátoru a volání metody font(withSize:) na deskriptoru.
import UIKit
// Vytvořit deskriptor písma pro rodinu
let descriptor = UIFontDescriptor.init(
fontAttributes: [
.family: "SF Pro",
.traits: [
.weight: UIFont.Weight.bold
]
]
)
// Generovat UIFont z deskriptoru
let font = descriptor.font(withSize: 17)
Tento přístup zaručuje, že systém vybere nejlepší shodu pro tučný řez SF Pro na aktuálním zařízení. Klíčová výhoda — kód nezávisí na verzi iOS: na iOS 13 bude použit SF Pro, na starších verzích — Helvetica Neue nebo výchozí systémové písmo.
Pro vytvoření písma s dynamickou velikostí se používá inicializátor se stylem textu a měřítkem. Dynamic Type automaticky přizpůsobuje velikost nastavení uživatele:
// Deskriptor Dynamic Type
let bodyDescriptor = UIFontDescriptor
.preferredFontDescriptor(withTextStyle: .body)
// Udělat písmo tučné
let boldDescriptor = bodyDescriptor.withSymbolicTraits([.traitBold])
// Generovat UIFont zachovávající dynamickou velikost
let boldBodyFont = UIFont(
descriptor: boldDescriptor!,
size: bodyDescriptor.pointSize
)
Důležité: metoda withSymbolicTraits vrací volitelný deskriptor — pokud požadovaný řez není k dispozici, vrací nil. Vždy před použitím zkontrolujte volitelný typ.
Font Descriptor podporuje neměnný model — každá metoda změny vrací nový deskriptor se změněným atributem. To odpovídá sémantice hodnoty a činí kód předvídatelným: původní deskriptor se nikdy nemění. Hlavní metody změny: addingAttributes pro přidávání atributů, withFace pro změnu řezu, withSize pro změnu velikosti, withMatrix pro afinní transformaci.
Metoda addingAttributes — nejflexibilnější. Přijímá slovník atributů a vrací nový deskriptor. Při shodě klíčů nové hodnoty nahrazují staré. To umožňuje kombinovat změny: přidat váhu, změnit velikost a povolit ligatury jedním voláním. Podle Apple Technical Q&A QA1682 je addingAttributes doporučeným způsobem hromadné změny prostřednictvím rozšíření.
Praktické použití: vytvoření písma pro monospace text v editoru kódu. Vývojář vezme systémový monospace deskriptor, přidá sníženou váhu pro tenké linky a zvýší mezery mezi znaky pomocí featureSettings. To poskytuje čitelnější kód bez načítání samostatného písma.
let monoDescriptor = UIFontDescriptor.monospacedDigitFontDescriptor()
// Přidat vlastní atributy
let customDescriptor = monoDescriptor.addingAttributes([
.size: 14,
.traits: [
.weight: UIFont.Weight.medium
]
])
let monoFont = UIFont(
descriptor: customDescriptor,
size: 14
)
Omezení: ne všechny atributy lze po vytvoření deskriptoru změnit. Například rodina písma (family) se nastavuje jednou při inicializaci. Pokud potřebujete změnit rodinu, vytvořte nový deskriptor. To souvisí s architekturou Core Text, kde je deskriptor vázán na konkrétní zdroj písma.
Párování písem — klíčová funkce Font Descriptor, která automaticky vybírá nejlepší shodu pro požadované atributy z nainstalovaných písem. Proces zahrnuje tři fáze: filtrování (vyloučení nekompatibilních písem), řazení (seřazení podle stupně shody) a výběr (vrácení nejlepšího výsledku). Párování se provádí na úrovni Core Text — frameworku, který je základem celé typografie iOS.
Pro vyhledání všech písem odpovídajících deskriptoru se používá metoda matchingFontDescriptors. Vrací pole deskriptorů seřazených podle relevance. Vývojář může zvolit přesnou shodu (první prvek) nebo procházet varianty pro vlastní logiku. Podle Apple Font Handling Guide je to jediný způsob, jak získat seznam dostupných řezů pro konkrétní rodinu bez výčtu podle názvu.
Scénář použití: při výběru písma v rozhraní nastavení textu. Uživatel vybere rodinu a aplikace přes matchingFontDescriptors získá všechny dostupné řezy a zobrazí je v pickeru. Bez párování byste museli pevně zakódovat seznam variant, který se mění mezi verzemi iOS.
let searchDescriptor = UIFontDescriptor.init(
fontAttributes: [.family: "SF Mono"]
)
// Získat všechny dostupné řezy
let matchingDescriptors = searchDescriptor
.matchingFontDescriptors(withMandatoryKeys: nil)
for descriptor in matchingDescriptors {
print(descriptor.object(forKey: .visibleName) ?? "unnamed")
}
Mandatory keys — parametr omezující vyhledávání. Pokud je zadáno [.family], párování vrátí všechna písma zadané rodiny. Pokud je zadáno [.family, .traits] — pouze ta, která se shodují jak rodinou, tak řezem. Použití mandatory keys urychluje párování při hledání podmnožiny písem.
Výkon: párování je synchronní operace trvající 0,5 až 5 ms na iOS. Pro jediné vyhledávání je to nepostřehnutelné, ale při hromadném procházení deskriptorů (např. v pickeru s 50+ písmy) se doporučuje ukládání výsledků do mezipaměti. Apple doporučuje provést párování jednou při načítání obrazovky a uložit pole deskriptorů.
Core Text — nízkoúrovňový C framework pro práci s typografií na iOS a macOS. Jeho protějšek UIFontDescriptor — CTFontDescriptor, který poskytuje stejné možnosti na úrovni Core Foundation. CTFontDescriptor se používá v API Core Text pro vytváření písem, měření textu a vykreslování složité typografie. UIFontDescriptor je v podstatě Objective-C obal kolem CTFontDescriptor s rozšířenou sadou atributů.
Toll-free bridging mezi UIFontDescriptor a CTFontDescriptor umožňuje předávání deskriptorů mezi UIKit a Core Text bez konverze. To je klíčové pro aplikace používající vlastní vykreslování textu — například textové editory založené na TextKit nebo editory kódu se zvýrazňováním syntaxe. Příklad: CTFontDescriptorCreateCopyWithAttribute vytváří kopii deskriptoru s přidaným atributem — obdoba addingAttributes z UIFontDescriptor.
Klíčový atribut kCTFontURLAttribute v CTFontDescriptor obsahuje URL souboru písma. To umožňuje určit, zda je písmo systémové nebo vlastní. Pro vlastní písma URL vede k souboru písma (.ttf nebo .otf), pro systémová — do systémové složky písem. Data přes deskriptor jsou pouze pro čtení; změna souboru písma přes URL není podporována.
Pro pokročilou typografii — vlastní ligatury, kontextové náhrady, alternativní glyfy — se používá CTFontDescriptorCopyAttribute s klíčem kCTFontFeatureSettingsAttribute. Tento atribut obsahuje pole slovníků funkcí OpenType, které lze přidat prostřednictvím deskriptoru. Podle Apple Core Text Programming Guide poskytuje kombinace UIFontDescriptor s Core Text plnou kontrolu nad typografií aplikace.
Často kladené otázky
UIFont — je hotové písmo připravené k použití, které vykresluje text. Font Descriptor — je popis písma, sada atributů, ze kterých lze vytvořit UIFont. Jeden deskriptor může vygenerovat více UIFont různých velikostí.
Ano. Pokud je písmo zaregistrováno v systému (přes Info.plist nebo Core Graphics), jeho deskriptor se vytvoří podle rodiny nebo názvu stejně jako pro systémová písma. Párování funguje pro všechna zaregistrovaná písma.
Použijte descriptor.object(forKey: .visibleName) pro zobrazovaný název nebo descriptor.postscriptName pro název PostScript. PostScript název se používá při vytváření písma přes UIFont(name:size:).
Cascade list — je pole vnořených deskriptorů, které slouží jako záložní písma. Pokud hlavní písmo neobsahuje požadovaný znak, systém postupně kontroluje písma z cascade list. Používá se pro podporu emoji a CJK znaků.
Ano. SwiftUI podporuje Font Descriptor přes Font(descriptor:size:). SwiftUI obal přijímá UIFontDescriptor a vytváří SwiftUI písmo, přičemž zachovává všechny atributy deskriptoru — kerning, ligatury a řez.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také