I have added a convenience constructor to NSMutableAttributedString
to accept a String
of HTML and a font.
extension NSMutableAttributedString {
// Convert HTML, but override the font. This copies the symbolic traits from the source font, so things like
// bold and italic are honored.
convenience init?(html: String, font: UIFont) {
guard let data = html.data(using: .utf16, allowLossyConversion: true) else {
preconditionFailure("string->data can't fail when lossy conversion is allowed")
}
do {
try self.init(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)
enumerateAttribute(.font, in: NSMakeRange(0, length), options: .longestEffectiveRangeNotRequired) { value, range, stop in
guard
let currentFont = value as? UIFont,
let newDescriptor = font.fontDescriptor.withSymbolicTraits(currentFont.fontDescriptor.symbolicTraits)
else {
return
}
let newFont = UIFont(descriptor: newDescriptor, size: font.pointSize)
addAttribute(.font, value: newFont, range: range)
}
} catch {
return nil
}
}
}
I'm running some HTML using ol
and ul
tags through this and placing them on a label.
let html = [
"<ul>",
"<li>not a link</li>",
"<li>",
"<a href=\"https://www.google.com\">link</a>",
"</li>",
"<li>",
"<strong><a href=\"https://www.google.com\">bold link</a></strong>",
"</li>",
"<li>",
"<em><a href=\"https://www.google.com\">italic link</a></em>",
"</li>",
"</ul>",
"<ol>",
"<li>not a link</li>",
"<li>",
"<a href=\"https://www.google.com\">link</a>",
"</li>",
"<li>",
"<strong><a href=\"https://www.google.com\">bold link</a></strong>",
"</li>",
"<li>",
"<em><a href=\"https://www.google.com\">italic link</a></em>",
"</li>",
"</ol>",
].joined(separator: "\n")
guard let string = NSMutableAttributedString(html: html, font: UIFont.systemFont(ofSize: 18)) else {
fatalError()
}
label.attributedText = string
When I place this into the label the bullets and numbers are bold, italic, and blue links, even though the strong
, em
, and a
tags are inside the li
.
I'm guessing this is a bug in NS(Mutable)AttributedString
and am prepared to file a radar, but I wanted to see if StackOverflow can find a bug in my code first.