Hi i have a problem when im parsing a Html to NSAtributtedString in a UILabel. The problem is in the strong text, the result is too bold (I guess when parsing the font is changed to "GibsonBold" and I need GibsonSemibold, or even change from Regular to Medium. I tried change tag to < b > or implement an style, but the result is always the same. Also I tried several extensions but I came out whit the same result.
This is the html String:
"<p>First text <strong> this text should be at lest Semibold</strong>. Final text.</p>"
Im using this two extension to parsing:
extension UIColor {
var hexString:String? {
if let components = self.cgColor.components {
let r = components[0]
let g = components[1]
let b = components[2]
return String(format: "XXX", (Int)(r * 255), (Int)(g * 255), (Int)(b * 255))
}
return nil
}
}
extension String {
var html2Attributed: NSAttributedString? {
do {
guard let data = data(using: String.Encoding.utf8) else {
return nil
}
return try NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
} catch {
print("error: ", error)
return nil
}
}
var htmlAttributed: (NSAttributedString?, NSDictionary?) {
do {
guard let data = data(using: String.Encoding.utf8) else {
return (nil, nil)
}
var dict:NSDictionary?
dict = NSMutableDictionary()
return try (NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: &dict), dict)
} catch {
print("error: ", error)
return (nil, nil)
}
}
func htmlAttributed(using font: UIFont, color: UIColor, lineHeight: CGFloat) -> NSAttributedString? {
do {
let htmlCSSString = "<style>"
"html *"
"{"
"font-size: \(font.pointSize * 0.75)pt !important;"
"color: #\(color.hexString!) !important;"
"font-family: \(font.familyName), Helvetica !important;"
"line-height: \(lineHeight * 0.06) !important;"
"}</style> \(self)"
guard let data = htmlCSSString.data(using: String.Encoding.utf8) else {
return nil
}
return try NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
} catch {
print("error: ", error)
return nil
}
}
}
And the implementation in label:
descriptionLabelText.attributedText = description.htmlAttributed(using: UIFont.gibsonRegular.withAdjustedSize(16),
color: .greyscale800,
lineHeight: 20.adjusted)
CodePudding user response:
Currently all the css styling only defines the font to use and the font size, not really the style
(bold, italic, regular etc) or the weights
(normal, bold, light etc) so these tags pick up the default styles of the tag.
I created the following HTML
let htmlString
= "<p>Normal text <strong> Strong set to 600 font weight </strong>. <b> Bold set to italic style </b>"
And then I use your code like this
label.attributedText = htmlString.htmlAttributed(using: UIFont(name: "Gibson-Regular",
size: 16)!,
color: .red,
lineHeight: 20)
This gives me the following result as you probably see now
If you added all the fonts (Gibson regular, bold, italic) to your file system properly, you can add specific styles in your CSS.
Small changes to your func htmlAttributed
func htmlAttributed(using font: UIFont,
color: UIColor,
lineHeight: CGFloat) -> NSAttributedString? {
do {
let htmlCSSString = "<style>"
"html *"
"{"
"font-size: \(font.pointSize * 0.75)pt !important;"
"color: #\(color.hexString!) !important;"
"font-family: \(font.familyName), Helvetica !important;"
"line-height: \(lineHeight * 0.06) !important;"
"}"
// customize bold
"b"
"{"
"font-size: \(font.pointSize * 0.75)pt !important;"
"font-style: italic;" // I set bold to be italic
"font-family: \(font.familyName), Helvetica !important;"
"line-height: \(lineHeight * 0.06) !important;"
"}"
// customize strong font weight
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
"strong"
"{"
"font-size: \(font.pointSize * 0.75)pt !important;"
"font-weight: 600;" // customize weight to what you want
"font-family: \(font.familyName), Helvetica !important;"
"line-height: \(lineHeight * 0.06) !important;"
"}"
"}</style> \(self)"
guard let data = htmlCSSString.data(using: String.Encoding.utf8) else {
return nil
}
return try NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
} catch {
print("error: ", error)
return nil
}
}
With this change you will see some changes to the weight of the strong
tag and I made the b
tag render as italics
Finally, as far as I know, you cannot set the weight to Semi Bold
so if you want to use the Semi Bold
font, you have explicitly set this as the font you want to use.
So you can customize the strong tag:
// I set font family to Gibson italic for example
// You can set it to semi bold font
"strong"
"{"
"font-size: \(font.pointSize * 0.75)pt !important;"
"font-family: \(UIFont(name: "Gibson-Italic", size: 16)!), Helvetica !important;"
"line-height: \(lineHeight * 0.06) !important;"
"}"
I think this should give you some ideas on how to customize to suit your solution