З’єднавши відповіді всіх, я зробив два розширення, які дозволяють встановити мітку з текстом html. Деякі відповіді вище неправильно інтерпретували сімейство шрифтів у атрибутованих рядках. Інші були неповними для моїх потреб або провалювалися іншими способами. Дайте мені знати, чи є щось, що ви хотіли б від мене покращити.
Я сподіваюся, що це комусь допоможе.
extension UILabel {
/// Sets the label using the supplied html, using the label's font and font size as a basis.
/// For predictable results, using only simple html without style sheets.
/// See /programming/19921972/parsing-html-into-nsattributedtext-how-to-set-font
///
/// - Returns: Whether the text could be converted.
@discardableResult func setAttributedText(fromHtml html: String) -> Bool {
guard let data = html.data(using: .utf8, allowLossyConversion: true) else {
print(">>> Could not create UTF8 formatted data from \(html)")
return false
}
do {
let mutableText = try NSMutableAttributedString(
data: data,
options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
mutableText.replaceFonts(with: font)
self.attributedText = mutableText
return true
} catch (let error) {
print(">>> Could not create attributed text from \(html)\nError: \(error)")
return false
}
}
}
extension NSMutableAttributedString {
/// Replace any font with the specified font (including its pointSize) while still keeping
/// all other attributes like bold, italics, spacing, etc.
/// See /programming/19921972/parsing-html-into-nsattributedtext-how-to-set-font
func replaceFonts(with font: UIFont) {
let baseFontDescriptor = font.fontDescriptor
var changes = [NSRange: UIFont]()
enumerateAttribute(.font, in: NSMakeRange(0, length), options: []) { foundFont, range, _ in
if let htmlTraits = (foundFont as? UIFont)?.fontDescriptor.symbolicTraits,
let adjustedDescriptor = baseFontDescriptor.withSymbolicTraits(htmlTraits) {
let newFont = UIFont(descriptor: adjustedDescriptor, size: font.pointSize)
changes[range] = newFont
}
}
changes.forEach { range, newFont in
removeAttribute(.font, range: range)
addAttribute(.font, value: newFont, range: range)
}
}
}