Font Descriptorは、iOSのUIFontDescriptorおよびmacOSのNSFontDescriptorオブジェクトであり、フォントのすべてのメタデータ(ファミリー、タイプフェイス、サイズ、文字間隔、行間隔、タイポグラフィ属性)をカプセル化します。UIFont(name:size:)を介して直接フォントを作成する代わりに、開発者は記述子を通じて希望する特性を記述し、システムが利用可能なフォントから最適な一致を選択します。Appleデベロッパドキュメントによると、UIFontDescriptorは20以上のフォント属性をサポートし、UIKitからCore Text、SwiftUIに至るまで、すべてのiOSタイポグラフィフレームワークで使用されています。
重要なポイント
Font Descriptorは、特定のフォントファイルではなく、キーと値のペアのセットとしてフォント特性を記述するオブジェクトです。名前でフォントを作成する代わりに、開発者はファミリー、タイプフェイス、サイズ、オプションの属性を指定し、システムが最適な一致を選択します。このアプローチは適応型タイポグラフィにとって重要です。同じ記述子が、利用可能なフォントセットが異なる異なるiOSバージョンでも機能します。iOSヒューマンインターフェイスガイドラインによると、記述子によるフォントマッチングが動的フォントを扱う推奨方法です。
Font Descriptorがない場合、開発者は各フォントの可用性を名前で確認し、手動でフォールバックオプションを定義する必要があります。記述子はこのプロセスを自動化します。タイプフェイスの互換性マトリックス(標準、太字、斜体、太字斜体)を含み、正確な一致が見つからない場合、最も近い利用可能なものを返します。システムマッチングはCore Textレベルで機能し、統一されたNSFontDescriptor APIを介してiOSとmacOSの両方で利用できます。
記述子はカスタムフォント(Info.plistを介してロードされるか手動で追加される)にも使用されます。フォントがシステムに登録されている場合、その記述子はシステムフォントとまったく同じ方法で作成されます。クロスプラットフォーム注記:記述子の概念はAndroidでもTypeface.Builderを通じて存在しますが、UIFontDescriptorを介したiOS実装は、Androidの5つに対して20以上の属性と、はるかに多くの属性を提供します。
UIFontDescriptorには、[UIFontDescriptor.AttributeName: Any]型のfontAttributesディクショナリにグループ化された属性が含まれています。主要な属性には、フォントファミリー、名前、サイズ、特性、変換マトリックス、オプティカルサイズ、テキストスタイルが含まれます。Apple WWDC 2019セッション227によると、テキストスタイル(Dynamic Type)の使用は、アクセシビリティ対応アプリケーションに必須です。
traits属性は、シンボリック特性を含むディクショナリです:ウェイト(UIFontWeightTrait)、傾き(UIFontSlantTrait)、幅(UIFontWidthTrait)など。これらの値はフォントマッチャーがタイプフェイスを選択するために使用します。たとえば、UIFontWeightTraitの値0.0は標準タイプフェイス、0.3は太字を示します。システムは数値を利用可能なフォントバリアントに自動的にマッピングします。
追加の属性には、OpenType機能のfeatureSettings(リガチャ、カーニング、数字のプロポーション)、ユーザー表示用のvisibleName、フォントのアフィン変換用のmatrix、カスケードフォールバックフォントリスト用のcascadeListが含まれます。属性の完全なリストは、iOSとmacOSの実質的にすべてのタイポグラフィシナリオをカバーしています。
| 属性 | タイプ | 説明 |
|---|---|---|
| UIFontDescriptorFamily | String | フォントファミリー(SF Pro、Helvetica Neue) |
| UIFontDescriptorName | String | フォントの完全な名前(HelveticaNeue-Bold) |
| UIFontDescriptorSize | NSNumber | ポイント単位のフォントサイズ |
| UIFontDescriptorMatrix | NSValue | アフィン変換マトリックス |
| UIFontDescriptorTraits | [String: Any] | タイプフェイスのシンボリック特性 |
| UIFontDescriptorTextStyle | String | Dynamic Typeスタイル(headline、body、caption) |
iOSでFont Descriptorを操作する主な方法は、記述子を作成し、それからUIFontを生成することです。これは、正確な名前を知らずに特定の特性を持つフォントが必要な場合の推奨アプローチです。プロセスは2つのステップで構成されます:イニシャライザを介してUIFontDescriptorを作成し、記述子でfont(withSize:)メソッドを呼び出します。
import UIKit
// ファミリーのフォント記述子を作成
let descriptor = UIFontDescriptor.init(
fontAttributes: [
.family: "SF Pro",
.traits: [
.weight: UIFont.Weight.bold
]
]
)
// 記述子からUIFontを生成
let font = descriptor.font(withSize: 17)
このアプローチにより、システムは現在のデバイスでSF Proの太字タイプフェイスに最適な一致を選択します。主な利点 — コードはiOSバージョンに依存しません:iOS 13ではSF Proが使用され、以前のバージョンではHelvetica Neueまたはデフォルトのシステムフォントが使用されます。
動的サイズのフォントを作成するには、テキストスタイルとスケールを指定してイニシャライザを使用します。Dynamic Typeはユーザーの設定に応じて自動的にサイズを調整します:
// Dynamic Type記述子
let bodyDescriptor = UIFontDescriptor
.preferredFontDescriptor(withTextStyle: .body)
// フォントを太字にする
let boldDescriptor = bodyDescriptor.withSymbolicTraits([.traitBold])
// 動的サイズを保持してUIFontを生成
let boldBodyFont = UIFont(
descriptor: boldDescriptor!,
size: bodyDescriptor.pointSize
)
重要:withSymbolicTraitsメソッドはオプショナルな記述子を返します — 要求されたタイプフェイスが利用できない場合、nilを返します。使用前に必ずオプショナルを確認してください。
Font Descriptorは不変モデルをサポートしています — 各変更メソッドは、変更された属性を持つ新しい記述子を返します。これは値セマンティクスに従い、コードを予測可能にします:元の記述子は決して変更されません。主な変更メソッドは次のとおりです:属性を追加するaddingAttributes、タイプフェイスを変更するwithFace、サイズを変更するwithSize、アフィン変換のwithMatrix。
addingAttributesメソッドが最も柔軟です。属性のディクショナリを受け取り、新しい記述子を返します。キーが一致すると、新しい値が古い値を置き換えます。これにより、単一の呼び出しでウェイトの追加、サイズの変更、リガチャの有効化を組み合わせることができます。AppleテクニカルQ&A QA1682によると、addingAttributesは拡張機能を介した一括変更の推奨方法です。
実用的な使用例:コードエディタで等幅テキスト用のフォントを作成する。開発者はシステム等幅記述子を取得し、細い線用に低いウェイトを追加し、featureSettingsを介して文字間隔を広げます。これにより、別のフォントをロードせずに読みやすいコードが得られます。
let monoDescriptor = UIFontDescriptor.monospacedDigitFontDescriptor()
// カスタム属性を追加
let customDescriptor = monoDescriptor.addingAttributes([
.size: 14,
.traits: [
.weight: UIFont.Weight.medium
]
])
let monoFont = UIFont(
descriptor: customDescriptor,
size: 14
)
制限:記述子作成後にすべての属性を変更できるわけではありません。たとえば、フォントファミリーは初期化時に一度設定されます。ファミリーを変更する必要がある場合は、新しい記述子を作成してください。これは、記述子が特定のフォントリソースに結び付けられているCore Textアーキテクチャに関連しています。
フォントマッチングはFont Descriptorの主要機能であり、インストールされているフォントの中から要求された属性に最も一致するものを自動的に選択します。プロセスには3つの段階があります:フィルタリング(互換性のないフォントの除外)、ランキング(一致度による並べ替え)、選択(最良の結果の返却)。マッチングは、すべてのiOSタイポグラフィの基盤となるフレームワークであるCore Textレベルで実行されます。
記述子に一致するすべてのフォントを見つけるには、matchingFontDescriptorsメソッドを使用します。関連性でソートされた記述子の配列を返します。開発者は正確な一致(最初の要素)を選択するか、カスタムロジックのためにオプションを反復処理できます。Appleフォントハンドリングガイドによると、これは名前で列挙せずに特定のファミリーで利用可能なタイプフェイスのリストを取得する唯一の方法です。
使用例:テキスト設定インターフェイスでフォントを選択する場合。ユーザーがファミリーを選択し、アプリケーションはmatchingFontDescriptorsを使用してすべての利用可能なタイプフェイスを取得し、ピッカーに表示します。マッチングがない場合、開発者はiOSバージョン間で変化するオプションのリストをハードコードする必要があります。
let searchDescriptor = UIFontDescriptor.init(
fontAttributes: [.family: "SF Mono"]
)
// 利用可能なすべてのタイプフェイスを取得
let matchingDescriptors = searchDescriptor
.matchingFontDescriptors(withMandatoryKeys: nil)
for descriptor in matchingDescriptors {
print(descriptor.object(forKey: .visibleName) ?? "unnamed")
}
必須キー — 検索を制限するパラメータ。[.family]を指定すると、マッチングは指定されたファミリーのすべてのフォントを返します。[.family, .traits]を指定すると、ファミリーとタイプフェイスの両方に一致するもののみを返します。必須キーを使用すると、フォントのサブセットを検索する際にマッチングが高速化されます。
パフォーマンス:マッチングは同期操作で、iOSでは0.5〜5ミリ秒かかります。単一の検索では無視できますが、記述子の一括反復処理(50以上のフォントがあるピッカーなど)では、結果をキャッシュすることをお勧めします。Appleは、画面読み込み時に一度マッチングを実行し、記述子の配列を保存することを推奨しています。
Core Textは、iOSおよびmacOSでタイポグラフィを扱うための低レベルCベースのフレームワークです。UIFontDescriptorに対応するものはCTFontDescriptorで、Core Foundationレベルで同じ機能を提供します。CTFontDescriptorは、フォントの作成、テキストの測定、複雑なタイポグラフィのレンダリングにCore Text APIで使用されます。UIFontDescriptorは、本質的に拡張された属性セットを持つCTFontDescriptorのObjective-Cラッパーです。
UIFontDescriptorとCTFontDescriptorの間のトールフリーブリッジにより、変換なしでUIKitとCore Textの間で記述子を渡すことができます。これは、カスタムテキストレンダリングを使用するアプリケーション — たとえば、TextKitベースのテキストエディタやシンタックスハイライト付きのコードエディタ — にとって重要です。例:CTFontDescriptorCreateCopyWithAttributeは、属性が追加された記述子のコピーを作成します — UIFontDescriptorのaddingAttributesに類似しています。
CTFontDescriptorの主要属性kCTFontURLAttributeには、フォントファイルのURLが含まれています。これにより、フォントがシステムフォントかカスタムフォントかを判断できます。カスタムフォントの場合、URLはフォントファイル(.ttfまたは.otf)を指します。システムフォントの場合は、システムフォントディレクトリを指します。記述子を介したデータは読み取り専用です。URLを介したフォントファイルの変更はサポートされていません。
高度なタイポグラフィ — カスタムリガチャ、コンテキスト置換、代替グリフ — には、kCTFontFeatureSettingsAttributeキーを指定してCTFontDescriptorCopyAttributeを使用します。この属性には、記述子を介して追加できるOpenType機能ディクショナリの配列が含まれています。Apple Core Textプログラミングガイドによると、UIFontDescriptorとCore Textを組み合わせることで、アプリケーションのタイポグラフィを完全に制御できます。
よくある質問
UIFontはテキストをレンダリングする使用準備のできたフォントです。Font Descriptorはフォントの説明 — UIFontを作成できる属性のセットです。1つの記述子から異なるサイズの複数のUIFontを生成できます。
はい。フォントがシステムに登録されている場合(Info.plistまたはCore Graphicsを介して)、その記述子はシステムフォントとまったく同じ方法でファミリーまたは名前によって作成されます。マッチングは登録されたすべてのフォントで機能します。
表示名を取得するにはdescriptor.object(forKey: .visibleName)を、PostScript名を取得するにはdescriptor.postscriptNameを使用します。PostScript名はUIFont(name:size:)でフォントを作成する際に使用されます。
カスケードリストは、フォールバックフォントとして機能するネストされた記述子の配列です。プライマリフォントが必要な文字を含まない場合、システムはカスケードリストからフォントを順次チェックします。絵文字やCJK文字のサポートに使用されます。
はい。SwiftUIはFont(descriptor:size:)を介してFont Descriptorをサポートしています。SwiftUIラッパーはUIFontDescriptorを受け入れ、すべての記述子属性(カーニング、リガチャ、タイプフェイス)を保持したSwiftUIフォントを作成します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。