Font Descriptor: kluczowe pojęcia i możliwości deskryptora czcionki

Autor: IT Sectr Opublikowano: 2026-07-23 Czas czytania: 9 min

Font Descriptor — to obiekt UIFontDescriptor w iOS i NSFontDescriptor w macOS, który hermetyzuje wszystkie metadane czcionki: rodzinę, krój, rozmiar, odstępy między znakami, odstępy między wierszami i atrybuty typograficzne. Zamiast tworzyć czcionkę bezpośrednio przez UIFont(name:size:), programista opisuje pożądane cechy przez deskryptor, a system dobiera najlepsze dopasowanie z dostępnych czcionek. Według Apple Developer Documentation, UIFontDescriptor obsługuje ponad 20 atrybutów czcionki i jest używany we wszystkich frameworkach typografii iOS — od UIKit przez Core Text aż po SwiftUI.

Najważniejsze

  • Font Descriptor — obiekt-opis czcionki zawierający metadane o rodzinie, kroju, rozmiarze i atrybutach typograficznych
  • Pozwala tworzyć UIFont z zestawu atrybutów bez podawania konkretnej nazwy czcionki
  • Obsługuje modyfikację istniejącej czcionki: zmianę rozmiaru, kroju, kerningu bez tworzenia nowego obiektu
  • Używany w UIKit, Core Text i SwiftUI do wyszukiwania i konfiguracji czcionek
  • Zapewnia dopasowanie czcionek — automatyczny dobór najbliższego dostępnego kroju

Czym jest Font Descriptor i do czego służy

Font Descriptor — to obiekt, który opisuje charakterystyki czcionki jako zestaw par klucz-wartość, a nie jako konkretny plik czcionki. Zamiast tworzyć czcionkę po nazwie, programista określa rodzinę, krój, rozmiar i opcjonalne atrybuty, a system dobiera najlepsze dopasowanie. Takie podejście jest kluczowe dla adaptacyjnej typografii: ten sam deskryptor może działać na różnych wersjach iOS, gdzie zestaw dostępnych czcionek się różni. Według iOS Human Interface Guidelines, dopasowanie czcionek przez deskryptory to zalecany sposób pracy z dynamicznymi czcionkami.

Bez Font Descriptor programista musiałby sprawdzać dostępność każdej czcionki po nazwie i ręcznie określać warianty zastępcze. Deskryptor automatyzuje ten proces: zawiera macierz kompatybilności krojów — normalny, pogrubiony, kursywa, pogrubiona kursywa — a w przypadku braku dokładnego dopasowania zwraca najbliższy dostępny. Systemowe dopasowanie działa na poziomie Core Text i jest dostępne zarówno na iOS, jak i na macOS przez jednolity interfejs NSFontDescriptor API.

Deskryptory są również używane dla czcionek niestandardowych — załadowanych przez Info.plist lub dodanych ręcznie. Jeśli czcionka jest zarejestrowana w systemie, jej deskryptor tworzy się dokładnie tak samo jak dla systemowej. Uwaga międzyplatformowa: koncepcja deskryptora istnieje również w Androidzie przez Typeface.Builder, ale implementacja iOS przez UIFontDescriptor daje znacznie więcej atrybutów — ponad 20 wobec 5 w Androidzie.

Podstawowe właściwości i atrybuty Font Descriptor

UIFontDescriptor zawiera atrybuty zgrupowane w słowniku fontAttributes typu [UIFontDescriptor.AttributeName: Any]. Kluczowe atrybuty obejmują rodzinę czcionki (family), nazwę (name), rozmiar (size), krój (traits), macierz transformacji (matrix), rozmiar optyczny (opticalSize) i styl tekstu (textStyle). Według Apple WWDC 2019 Session 227, używanie stylów tekstu — Dynamic Type — jest obowiązkowe dla aplikacji zgodnych z accessibility.

Atrybut traits — to słownik zawierający charakterystyki symboli: grubość (UIFontWeightTrait), kursywę (UIFontSlantTrait), szerokość (UIFontWidthTrait) i inne. Te wartości są używane przez mechanizm dopasowania czcionek do wyboru kroju. Na przykład UIFontWeightTrait z wartością 0.0 — normalny krój, 0.3 — pogrubiony. System automatycznie mapuje wartości liczbowe na dostępne warianty czcionki.

Dodatkowe atrybuty obejmują featureSettings dla funkcji OpenType (ligatury, kerning, proporcje cyfr), visibleName do wyświetlania użytkownikowi, matrix dla afinicznych transformacji czcionki oraz cascadeList dla kaskadowych list czcionek zastępczych. Pełna lista atrybutów pokrywa praktycznie wszystkie scenariusze typografii w iOS i macOS.

AtrybutTypOpis
UIFontDescriptorFamilyStringRodzina czcionki (SF Pro, Helvetica Neue)
UIFontDescriptorNameStringPełna nazwa czcionki (HelveticaNeue-Bold)
UIFontDescriptorSizeNSNumberRozmiar czcionki w punktach
UIFontDescriptorMatrixNSValueMacierz afiniczna transformacji
UIFontDescriptorTraits[String: Any]Charakterystyki symboliczne kroju
UIFontDescriptorTextStyleStringStyl Dynamic Type (headline, body, caption)

Tworzenie UIFont przez Font Descriptor w Swift

Podstawowy sposób pracy z Font Descriptor w iOS — utworzenie deskryptora z następną generacją UIFont. To preferowane podejście, gdy trzeba uzyskać czcionkę z określonymi cechami bez znajomości dokładnej nazwy. Proces składa się z dwóch kroków: utworzenie UIFontDescriptor przez inicjalizator i wywołanie metody font(withSize:) na deskryptorze.

swift
import UIKit

// Utwórz deskryptor czcionki dla rodziny
let descriptor = UIFontDescriptor.init(
    fontAttributes: [
        .family: "SF Pro",
        .traits: [
            .weight: UIFont.Weight.bold
        ]
    ]
)

// Generuj UIFont z deskryptora
let font = descriptor.font(withSize: 17)

To podejście gwarantuje, że system dobierze najlepsze dopasowanie dla pogrubionego kroju SF Pro na bieżącym urządzeniu. Kluczowa zaleta — kod nie zależy od wersji iOS: na iOS 13 zostanie użyty SF Pro, na wcześniejszych — Helvetica Neue lub domyślna czcionka systemowa.

Do tworzenia czcionki z dynamicznym rozmiarem używa się inicjalizatora ze stylem tekstu i skalą. Dynamic Type automatycznie dostosowuje rozmiar do ustawień użytkownika:

swift
// Deskryptor Dynamic Type
let bodyDescriptor = UIFontDescriptor
    .preferredFontDescriptor(withTextStyle: .body)

// Pogrub czcionkę
let boldDescriptor = bodyDescriptor.withSymbolicTraits([.traitBold])

// Generuj UIFont zachowując dynamiczny rozmiar
let boldBodyFont = UIFont(
    descriptor: boldDescriptor!,
    size: bodyDescriptor.pointSize
)

Ważne: metoda withSymbolicTraits zwraca opcjonalny deskryptor — jeśli żądany krój jest niedostępny, zwracana jest wartość nil. Zawsze sprawdzaj opcjonal przed użyciem.

Modyfikacja atrybutów przez dodawanie i zamianę

Font Descriptor obsługuje model niemutowalny — każda metoda modyfikacji zwraca nowy deskryptor ze zmienionym atrybutem. Odpowiada to semantyce wartości i czyni kod przewidywalnym: oryginalny deskryptor nigdy się nie zmienia. Główne metody modyfikacji: addingAttributes do dodawania atrybutów, withFace do zmiany kroju, withSize do zmiany rozmiaru, withMatrix do afinicznej transformacji.

Metoda addingAttributes — najbardziej elastyczna. Przyjmuje słownik atrybutów i zwraca nowy deskryptor. W przypadku zgodności kluczy nowe wartości zastępują stare. Pozwala to łączyć zmiany: dodać wagę, zmienić rozmiar i włączyć ligatury jednym wywołaniem. Według Apple Technical Q&A QA1682, addingAttributes to zalecany sposób masowej modyfikacji przez rozszerzenie.

Praktyczne zastosowanie: tworzenie czcionki dla tekstu o stałej szerokości w edytorze kodu. Programista bierze systemowy deskryptor monospace, dodaje zmniejszoną wagę dla cienkich linii i zwiększa odstępy między znakami przez featureSettings. Daje to bardziej czytelny kod bez ładowania osobnej czcionki.

swift
let monoDescriptor = UIFontDescriptor.monospacedDigitFontDescriptor()

// Dodaj niestandardowe atrybuty
let customDescriptor = monoDescriptor.addingAttributes([
    .size: 14,
    .traits: [
        .weight: UIFont.Weight.medium
    ]
])

let monoFont = UIFont(
    descriptor: customDescriptor,
    size: 14
)

Ograniczenie: nie wszystkie atrybuty można zmienić po utworzeniu deskryptora. Na przykład rodzina czcionki (family) jest ustawiana raz podczas inicjalizacji. Jeśli trzeba zmienić rodzinę, utwórz nowy deskryptor. Wynika to z architektury Core Text, gdzie deskryptor jest związany z konkretnym zasobem czcionki.

Dopasowanie czcionek i wyszukiwanie systemowe

Dopasowanie czcionek — kluczowa funkcja Font Descriptor, która automatycznie dobiera najlepsze dopasowanie do żądanych atrybutów spośród zainstalowanych czcionek. Proces obejmuje trzy etapy: filtracja (odrzucenie niezgodnych czcionek), rankingowanie (sortowanie według stopnia dopasowania) i wybór (zwrócenie najlepszego wyniku). Dopasowanie jest wykonywane na poziomie Core Text — frameworku leżącego u podstaw całej typografii iOS.

Do wyszukania wszystkich czcionek odpowiadających deskryptorowi używa się metody matchingFontDescriptors. Zwraca ona tablicę deskryptorów posortowanych według trafności. Programista może wybrać dokładne dopasowanie (pierwszy element) lub przeglądać warianty dla niestandardowej logiki. Według Apple Font Handling Guide, to jedyny sposób na uzyskanie listy dostępnych krojów dla konkretnej rodziny bez wyliczania po nazwie.

Scenariusz użycia: przy wyborze czcionki w interfejsie ustawień tekstu. Użytkownik wybiera rodzinę, a aplikacja przez matchingFontDescriptors pobiera wszystkie dostępne kroje i wyświetla je w pickerze. Bez dopasowania trzeba by sztywno kodować listę wariantów, która zmienia się między wersjami iOS.

swift
let searchDescriptor = UIFontDescriptor.init(
    fontAttributes: [.family: "SF Mono"]
)

// Pobierz wszystkie dostępne kroje
let matchingDescriptors = searchDescriptor
    .matchingFontDescriptors(withMandatoryKeys: nil)

for descriptor in matchingDescriptors {
    print(descriptor.object(forKey: .visibleName) ?? "unnamed")
}

Mandatory keys — parametr ograniczający wyszukiwanie. Jeśli podać [.family], dopasowanie zwróci wszystkie czcionki określonej rodziny. Jeśli podać [.family, .traits] — tylko te, które pasują zarówno do rodziny, jak i kroju. Użycie mandatory keys przyspiesza dopasowanie podczas wyszukiwania podzbioru czcionek.

Wydajność: dopasowanie to operacja synchroniczna zajmująca od 0.5 do 5 ms na iOS. Dla pojedynczego wyszukiwania jest to niezauważalne, ale przy masowym przeglądaniu deskryptorów (np. w pickerze z 50+ czcionkami) zaleca się buforowanie wyników. Apple zaleca wykonywanie dopasowania raz przy ładowaniu ekranu i zapisywanie tablicy deskryptorów.

Integracja z Core Text i CTFontDescriptor

Core Text — niskopoziomowy framework w języku C do pracy z typografią na iOS i macOS. Jego odpowiednik UIFontDescriptor — CTFontDescriptor, który zapewnia te same możliwości na poziomie Core Foundation. CTFontDescriptor jest używany w API Core Text do tworzenia czcionek, mierzenia tekstu i renderowania złożonej typografii. UIFontDescriptor w istocie jest nakładką Objective-C na CTFontDescriptor z rozszerzonym zestawem atrybutów.

Toll-free bridging między UIFontDescriptor a CTFontDescriptor pozwala przekazywać deskryptory między UIKit a Core Text bez konwersji. Jest to kluczowe dla aplikacji używających niestandardowego renderowania tekstu — na przykład edytorów tekstu opartych na TextKit lub edytorów kodu z podświetlaniem składni. Przykład: CTFontDescriptorCreateCopyWithAttribute tworzy kopię deskryptora z dodanym atrybutem — odpowiednik addingAttributes z UIFontDescriptor.

Key attribute kCTFontURLAttribute w CTFontDescriptor zawiera URL pliku czcionki. Pozwala to określić, czy czcionka jest systemowa, czy niestandardowa. Dla czcionek niestandardowych URL prowadzi do pliku czcionki (.ttf lub .otf), dla systemowych — do systemowego katalogu czcionek. Dane przez deskryptor są dostępne tylko do odczytu; zmiana pliku czcionki przez URL nie jest obsługiwana.

Do zaawansowanej typografii — niestandardowe ligatury, zamiany kontekstowe, alternatywne glify — używa się CTFontDescriptorCopyAttribute z kluczem kCTFontFeatureSettingsAttribute. Ten atrybut zawiera tablicę słowników funkcji OpenType, które można dodawać przez deskryptor. Według Apple Core Text Programming Guide, łączenie UIFontDescriptor z Core Text daje pełną kontrolę nad typografią aplikacji.

Często zadawane pytania

Czym różni się Font Descriptor od UIFont?

UIFont — to gotowa do użycia czcionka, która renderuje tekst. Font Descriptor — to opis czcionki, zestaw atrybutów, z których można utworzyć UIFont. Jeden deskryptor może wygenerować wiele UIFont o różnych rozmiarach.

Czy można użyć Font Descriptor dla niestandardowych czcionek?

Tak. Jeśli czcionka jest zarejestrowana w systemie (przez Info.plist lub Core Graphics), jej deskryptor tworzy się po rodzinie lub nazwie dokładnie tak samo jak dla czcionek systemowych. Dopasowanie działa dla wszystkich zarejestrowanych czcionek.

Jak uzyskać nazwę czcionki z deskryptora?

Użyj descriptor.object(forKey: .visibleName), aby uzyskać wyświetlaną nazwę, lub descriptor.postscriptName dla nazwy PostScript. Nazwa PostScript jest używana podczas tworzenia czcionki przez UIFont(name:size:).

Czym jest cascade list w Font Descriptor?

Cascade list — to tablica zagnieżdżonych deskryptorów, które służą jako czcionki zastępcze. Jeśli główna czcionka nie zawiera potrzebnego znaku, system kolejno sprawdza czcionki z cascade list. Używane do obsługi emoji i znaków CJK.

Czy Font Descriptor działa w SwiftUI?

Tak. SwiftUI obsługuje Font Descriptor przez Font(descriptor:size:). Nakładka SwiftUI przyjmuje UIFontDescriptor i tworzy czcionkę SwiftUI, zachowując wszystkie atrybuty deskryptora — kerning, ligatury i krój.

Podsumowanie

  • Font Descriptor — obiekt-opis czcionki z atrybutami rodziny, kroju, rozmiaru i cech typograficznych
  • Pozwala tworzyć UIFont z zestawu atrybutów z automatycznym dopasowaniem czcionek
  • Obsługuje niemutowalną modyfikację przez addingAttributes, withSize, withSymbolicTraits
  • matchingFontDescriptors zwraca wszystkie dostępne kroje do wyszukiwania i wyboru czcionek
  • Integruje się z Core Text przez toll-free bridging między UIFontDescriptor i CTFontDescriptor
  • Obsługuje Dynamic Type przez preferowane style tekstu i skalowanie
  • Zalecany do adaptacyjnej typografii obsługującej wszystkie wersje iOS bez sprawdzania dostępności czcionek

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również