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


調べたこと
UISearchBarのビュー構造
UIsearchBarのView Hierarchyをデバッグしてみると、テキストが載っているビューが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)

上記の各プロパティはgetプロパティのため、直接値を調整することはできません。
対応方法
頑張って対応するのであれば、以下のように編集後にNSAttributedString
のbaselineOffset
を調整することができます。
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
let attributedString: NSAttributedString = NSAttributedString(string: searchBar.text ?? "", attributes: [.baselineOffset: 9])
searchBar.searchTextField.attributedText = attributedString
}
余談
UISearchBarでフォントを指定すると何故だかcornerRadius
が効かなくなりました。。。
終わりに
iOSは日本語フォントへの対応が遅い(今後も対応されない可能性が高い)ため、どうしてもカスタムフォントを使用したいというこだわりがなければ、システムフォントを使用するのが良いと思います。
もしこだわりたい場合は、上記のような調整することは可能ですが、思わぬ不具合に遭遇したり、iOSバージョンによって対応する必要があります。またUISearchBar以外にも調整が必要なコンポーネントがあるかもしれないです。
とはいえ、フォントにまでこだわりを持って開発することは素晴らしいことだと思います。
本記事とは関係ないですが、メルカリのオリジナルフォントの制作秘話とかはとても面白くて、フォントにこだわるのカッコ良いなと思いました。
参考文献
この記事は以下の情報を参考に書きました。