iOS15以降でUISearchBarにカスタムフォント(NotoSansJapanese)を指定すると、テキストのベースラインがずれてしまう

はじめに

iOS15以降で、UISearchBarのsearchTextField.fontプロパティにNotoSansJapaneseを指定した際に、編集完了するとテキストのベースラインがずれる現象に遭遇したため、原因とその対応についてまとめました。

編集中
編集後

調べたこと

UISearchBarのビュー構造

UIsearchBarのView Hierarchyをデバッグしてみると、テキストが載っているビューがiOS15で変更されていました。

iOS14以前
iOS15以降

システムフォントとNotoSansJapaneseの違い

フォントサイズを17ptとしたとき、フォントごとの各プロパティを確認してみました。

システムフォント

ascender: Optional(16.1865234375)
descender: Optional(-4.1005859375)
lineHeight: Optional(20.287109375)
capHeight: Optional(11.97802734375)
pointSize: Optional(17.0)
leading: Optional(0.0)

NotoSansJapanese

ascender: Optional(19.720000000000002)
descender: Optional(-4.896000000000001)
lineHeight: Optional(24.616000000000003)
capHeight: Optional(12.461)
pointSize: Optional(17.0)
leading: Optional(0.0)
参考) Text Programming Guide for iOS

上記の各プロパティはgetプロパティのため、直接値を調整することはできません。

対応方法

頑張って対応するのであれば、以下のように編集後にNSAttributedStringbaselineOffsetを調整することができます。

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
  let attributedString: NSAttributedString = NSAttributedString(string: searchBar.text ?? "", attributes: [.baselineOffset: 9])
  searchBar.searchTextField.attributedText = attributedString
}

余談

UISearchBarでフォントを指定すると何故だかcornerRadiusが効かなくなりました。。。

終わりに

iOSは日本語フォントへの対応が遅い(今後も対応されない可能性が高い)ため、どうしてもカスタムフォントを使用したいというこだわりがなければ、システムフォントを使用するのが良いと思います。

もしこだわりたい場合は、上記のような調整することは可能ですが、思わぬ不具合に遭遇したり、iOSバージョンによって対応する必要があります。またUISearchBar以外にも調整が必要なコンポーネントがあるかもしれないです。

とはいえ、フォントにまでこだわりを持って開発することは素晴らしいことだと思います。
本記事とは関係ないですが、メルカリのオリジナルフォントの制作秘話とかはとても面白くて、フォントにこだわるのカッコ良いなと思いました。

参考文献

この記事は以下の情報を参考に書きました。