【UIKit シリーズ】カスタムフォントを追加して使用する方法

# はじめに
XcodeでのiOS開発時、追加したカスタムフォントの使用に苦労しました。
カスタムフォントを追加して使用するために以下のことを理解しておくことが大切です。

それは、**フォントファイルには複数のフォントスタイルが含まれている場合があり、ファイル名、フォントファミリー名、フォントスタイル名はそれぞれ異なる概念であるということ**です。

このことを念頭に、どのような手順を踏めば確実に使用できるか記したいと思います。

# 対象読者
- XcodeのiOS開発でカスタムフォントを使用したい方！
- UIKitのソースコード上でカスタムフォントを使用したい方！
- フォントファイルで使用できるフォントスタイル名を確認したい方！

# 環境
Xcode version 15.3

# 今回やること

1. フォントファイルをダウンロード
2. フォントファイルをXcode Project に追加
3. Info.plist に項目を追加
4. 追加したフォントファイルのフォントファミリー名・スタイル名を確認
5. 追加したフォントをソースコード上で使用して実装

順に説明していきます。
(使用したいカスタムフォントがある方は、適宜置き換えて実装してください。)

[前回](https://qiita.com/generosity_hiroto_taniguchi/private/90f2465011dae6941cf1)と同様に、Interface に Storyboard を選択してプロジェクトを作成したもので解説していきます。

## 1. フォントファイルをダウンロード
ここでは、[こちら](https://fonts.google.com/selection?lang=en_Latn&categoryFilters=Feeling:%2FExpressive%2FFancy)から2つの**フォントファイル**をダウンロードして使用します。
 今回は、Neonderthaw と NotoSansJP をダウンロードしました。
 (今回は比較のため２つダウンロードしています。)

![00_download_font.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/bbd83726-c54d-8d93-2705-38fecc089230.png)

## 2. フォントファイルをXcode Project に追加
フォントファイルの形式は、**True Type Font (.ttf)** と **Open Type Font (.otf)** ファイルに対応しています。

ダウンロードした以下の2つのファイルをプロダクトに追加します。

- Neonderthaw-Regular.ttf
( **1つのスタイルのみの格納したファイル**)
- NotoSansJP-VariableFont_wght.ttf
(**複数のスタイルを含むファイル**)

![01_downloaded_customfonts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/8e27dc75-2af1-846a-aa9e-c3f1add68448.png)
今回は、Font フォルダにドラッグ&ドロップして追加しました。
追加する際には**Add to targets** を忘れずにチェックします。
![02_customfont.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/a83fd581-9796-559d-b525-6e7de6255d85.png)

:information_source: 補足
Add to targets は、プロジェクトビルド時にそのリソースをアプリケーションバンドルに含める指定する項目です。バンドルに含まれることで、そのリソースがアプリ実行時に利用可能となります。

## 3. Info.plist に項目を追加

Info.plistに "**Fonts provided by application**"というキーを追加します

![03_customfont_info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/7c4d7cd6-b2f9-8bdc-ba50-80abc25ab6b1.png)

項目としてフォントファイルの名前を追加します。名前の一部として**ファイル拡張子を含めること**に注意してください。

![04_infoplist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/225ce3b3-924f-d35f-067d-fc4bf6bac354.png)

## 4. 追加したフォントファイルのファミリー名・スタイル名の確認
ソースコード上で、使用したいフォントスタイルのフォントオブジェクト([UIFont](https://developer.apple.com/documentation/uikit/uifont))の生成方法は以下の通りです。
~~~swift
UIFont(name: "フォントスタイル名", size: サイズ)
~~~
第一引数には**フォントスタイル名**であることに注意して下さい。
(:warning: 決して**フォントファイル名**ではありません。)

追加したフォントファイルに含まれるフォントスタイル名を確認するために、以下のコードを　ViewController の viewDidLoad メソッド内に追加して下さい。

~~~swift:ViewController
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
    // フォントスタイル名の確認（デバッグ用）
    UIFont.familyNames.forEach { familyName in
        print("")
        print("Family: \(familyName)")
        UIFont.fontNames(forFamilyName: familyName).forEach { fontName in
            print("Font: \(fontName)")
        }
    }
}
~~~

実行してログを確認します。
以下は追加したフォントファイルに対応するログの一部抜粋したものです。

~~~

Family: Neonderthaw
Font: Neonderthaw-Regular

Family: Noto Sans JP
Font: NotoSansJP-Thin_Regular
Font: NotoSansJP-Thin
Font: NotoSansJP-Thin_ExtraLight
Font: NotoSansJP-Thin_Light
Font: NotoSansJP-Thin_Medium
Font: NotoSansJP-Thin_SemiBold
Font: NotoSansJP-Thin_Bold
Font: NotoSansJP-Thin_ExtraBold
Font: NotoSansJP-Thin_Black

~~~

ファミリー名(Family)とは呼ばれるフォントのスタイルをひとまとまりにした総称を指しています。

**Neonderthaw-Regular.ttf**ファイルには、**ファミリー名 Neonderthaw の Neonderthaw-Regularフォントスタイル**があります。

**NotoSansJP-VariableFont_wght.ttf**ファイルには、**ファミリー名 Noto Sans JP の NotoSansJP-Thin_Regularフォントスタイルなど複数**あります。

これでフォントファイルには、単一または複数のフォントスタイルが含まれていることが分かりました。

## 5. 追加したフォントをソースコード上で使用して実装

フォントファイルに対応したフォントスタイル名が確認できたので実際にソースコード上で使用してみます。
実装は以下の通りです。

~~~swift:ViewController
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // フォントスタイル Neonderthaw-Regular を設定したラベル
        let label = UILabel()
        label.frame = CGRect(x: 50, y: 200, width: 1000, height: 150)
        label.text = "Merry Christmas"
        label.font = UIFont(name: "Neonderthaw-Regular", size: 100.0)
        view.addSubview(label)

        // フォントスタイル NotoSansJP-Thin_Regular を設定したラベル
        let subLabel = UILabel()
        subLabel.frame = CGRect(x: 200, y: 400, width: 500, height: 150)
        subLabel.text = "メリークリスマス"
        subLabel.font = UIFont(name: "NotoSansJP-Thin_Regular", size: 50.0)
        view.addSubview(subLabel)
    }
}
~~~
以下が実行結果です。

![06_uiview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/75fc1c47-9f7d-ca05-fe10-a8f3b649d6cc.png)
正しく表示されることが確認できました。


### :information_source:  UIFont インスタンス生成時に気をつけること
存在しないフォントスタイル名で、実装した場合も確認します。
以下のように一部の実装を変更します。
~~~swift
subLabel.font = UIFont(name: "NotoSansJP-VariableFont_wght", size: 50.0)
~~~
以下が実行結果です。

![05_ipad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786602/4346a1cf-150b-e243-410f-12b6e7871739.png)

"メリークリスマス"の表記が正しく表示されないことを確認できました。
これは指定したフォントスタイルが存在しない場合起きてしまいます。
`UIFont(name:size:)`が`nil`を返し、デフォルトのシステムフォントが使用されてしまったのです。

なのでカスタムフォントの利用でうまくいかない場合は、以下の項目を改めて確認しましょう。

>- 指定したフォントスタイル名が存在するか
>- フォントファイルがビルド対象に含まれているか
（Add to targetsのチェック漏れ）
>- Info.plistに正しくフォントファイル名が登録されているか
 (拡張子の記入漏れ)

# まとめ
カスタムフォントを使用するまでの簡潔なフローは以下の通りです。

カスタムフォントファイルをXcodeプロダクトに追加。
(追加する際はAdd to targets にチェック。)
↓
Info.plist の Fonts provided by application にファイル名を追加。
(追加する際は拡張子も含める。)
↓
追加したファイルのフォントスタイル名(フォント名)を確認。

正しくカスタムフォントを実装するために、**フォントファイルに含まれるフォントスタイルを確認してから使用する**ことを忘れずに行いましょう！


# 参考文献

[公式ドキュメント Adding a Custom Font to Your App
](https://developer.apple.com/documentation/uikit/adding-a-custom-font-to-your-app)

[Common Mistakes With Adding Custom Fonts to Your iOS App](https://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/)