事象
iOS13でNSAttributedStringでフォントを装飾してUILabelにセットする際にフォントがSystem FontからTimes New Romanにレンダリングされ、結局何をすればいいのか困ったので記事にしました。(iOS13未満は期待動作です)
具体的には以下のようなコードです。
動作としてはHTMLのテキストをNSAttributedStringで加工し、fontName
, fontSize
自体は、labelに設定されているプロパティから取得しようとしています。
label.setHTMLFromString(htmlText: "<span>純粋はちみつ<br></span><span style=\"font-size : small\">風味豊かな純粋はちみつです。</span>"
extension UILabel {
func setHTMLFromString(htmlText: String) {
let modifiedFont = String(format:"<span style=\"font-family: '\(self.font.fontName)'; font-size: \(self.font.pointSize)\">%@</span>", htmlText)
guard let data = modifiedFont.data(using: .unicode, allowLossyConversion: true) else { return }
do {
let attrStr = try NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attrStr
} catch {
print("error: ", error)
}
}
}
Times New Romanになるとこんなに変わります。
System Font | Times New Roman |
---|---|
![]() |
![]() |
画面内の他のラベルとフォントが一致していないととても違和感があります🙃
原因
なぜかself.font.fontName
で取得しているフォントがiOS12とiOS13では異なり、systemFontとして認識されていないのが原因?
iOS12 | iOS13 |
---|---|
![]() |
![]() |
.SFUI-Regular
がsystemFontのFamily Nameとして認識しない??😫
結論
解決策1
フォントを上書きする。全体が上書きされる。少し強引。
label.font = UIFont.systemFont(ofSize: 17)
解決策2
formatに '-apple-system'
を加える。
let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', '\(self.font.fontName)'; font-size: \(self.font.pointSize)\">%@</span>", htmlText)
font-family:
のあとに'-apple-system',
を追加することによって、.SFUI-Regular
が無事にsystem Font
として認識されました☘️
今回の場合、HTMLの一部の部分を太字
にしたかったので、2番目の方法で対応しました。
Appleのバグ?かもしれないので今後も動向を追っていきたいと思います。
少しでも参考になれば幸いです😌