[英]Can I set default font when translating HTML into NSAttributedString?
我試圖在 UILabel 中顯示 HTML,比如
NSString * htmlString = @"Some html string \n <font size=\"13\" color=\"red\">This is some text!</font>";
NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
現在我得到一個 attributedString
打印 attrStr 的描述:一些 html 字符串
{
...
NSFont = "<UICTFont: 0x7f8240d7c310> font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; **font-size: 12.00pt**";
}
這是一些文字!
{
...
NSFont = "<UICTFont: 0x7f8240d7aff0> font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; **font-size: 37.00pt**";
}
似乎font-size: 12.00pt是默認大小,我想在不更改 HTML 源代碼的情況下更改大小。 怎么做?
您可以通過一點點編碼來完成...您需要檢查屬性並更改屬性字符串每個段的字體大小(如正常、斜體、粗體等...)。
extension String {
func htmlAttributedString() -> NSMutableAttributedString {
guard let data = self.data(using: String.Encoding.utf8, allowLossyConversion: false)
else { return NSMutableAttributedString() }
guard let formattedString = try? NSMutableAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil )
else { return NSMutableAttributedString() }
return formattedString
}
}
extension NSMutableAttributedString {
func with(font: UIFont) -> NSMutableAttributedString {
self.enumerateAttribute(NSAttributedStringKey.font, in: NSMakeRange(0, self.length), options: .longestEffectiveRangeNotRequired, using: { (value, range, stop) in
let originalFont = value as! UIFont
if let newFont = applyTraitsFromFont(originalFont, to: font) {
self.addAttribute(NSAttributedStringKey.font, value: newFont, range: range)
}
})
return self
}
func applyTraitsFromFont(_ f1: UIFont, to f2: UIFont) -> UIFont? {
let originalTrait = f1.fontDescriptor.symbolicTraits
if originalTrait.contains(.traitBold) {
var traits = f2.fontDescriptor.symbolicTraits
traits.insert(.traitBold)
if let fd = f2.fontDescriptor.withSymbolicTraits(traits) {
return UIFont.init(descriptor: fd, size: 0)
}
}
return f2
}
}
你會像這樣使用它
let formattedString = "text <b>sometext</b>"
.htmlAttributedString()
.with(font:UIFont(name: "Times New Roman", size: 37)!)
這是@Maria 在Swift 5.1 中重寫的 NSMutableAttributedString 擴展
extension NSMutableAttributedString {
func with(font: UIFont) -> NSMutableAttributedString {
enumerateAttribute(NSAttributedString.Key.font, in: NSMakeRange(0, length), options: .longestEffectiveRangeNotRequired, using: { (value, range, stop) in
if let originalFont = value as? UIFont, let newFont = applyTraitsFromFont(originalFont, to: font) {
addAttribute(NSAttributedString.Key.font, value: newFont, range: range)
}
})
return self
}
func applyTraitsFromFont(_ originalFont: UIFont, to newFont: UIFont) -> UIFont? {
let originalTrait = originalFont.fontDescriptor.symbolicTraits
if originalTrait.contains(.traitBold) {
var traits = newFont.fontDescriptor.symbolicTraits
traits.insert(.traitBold)
if let fontDescriptor = newFont.fontDescriptor.withSymbolicTraits(traits) {
return UIFont.init(descriptor: fontDescriptor, size: 0)
}
}
return newFont
}
}
這是我的版本,支持文本樣式(正文、標題等)、文本對齊並可直接在UILabel
:
UILabel
擴展:
import UIKit
extension UILabel {
// See: https://stackoverflow.com/questions/34263767/can-i-set-default-font-when-translating-html-into-nsattributedstring
func set(html: String, textAligment: NSTextAlignment = NSTextAlignment.natural) {
let textStyle = self.font.fontDescriptor.object(forKey: UIFontDescriptor.AttributeName.textStyle) as! UIFont.TextStyle
do {
self.attributedText = try html.htmlAttributedString(textAligment: textAligment).with(textStyle: textStyle)
} catch let e {
print("Couldn\'t parse \'\(html)\': \(e.localizedDescription)")
}
}
}
String
擴展:
import Foundation
extension String {
enum StringToHTMLError: Error {
case encoding
}
func htmlAttributedString(textAligment: NSTextAlignment = NSTextAlignment.natural) throws -> NSMutableAttributedString {
guard let data = self.data(using: String.Encoding.utf8, allowLossyConversion: false) else {
throw StringToHTMLError.encoding
}
let text = try NSMutableAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil )
// See: https://stackoverflow.com/a/33443521/5189200
let style = NSMutableParagraphStyle()
style.alignment = textAligment
text.addAttributes([.paragraphStyle: style],
range: NSMakeRange(0, text.length))
return text
}
}
和NSMutableAttributedString
擴展:
import Foundation
extension NSMutableAttributedString {
func with(textStyle: UIFont.TextStyle) -> NSMutableAttributedString {
self.enumerateAttribute(NSAttributedString.Key.font, in: NSMakeRange(0, self.length), options: .longestEffectiveRangeNotRequired, using: { (value, range, stop) in
let originalFont = value as! UIFont
if let newFont = applyTraitsFromFont(originalFont, to: textStyle) {
self.addAttribute(NSAttributedString.Key.font, value: newFont, range: range)
}
})
return self
}
private func applyTraitsFromFont(_ f1: UIFont, to textStyle: UIFont.TextStyle) -> UIFont? {
let originalTrait = f1.fontDescriptor.symbolicTraits
let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle)
if originalTrait.contains(.traitBold) {
var traits = fontDescriptor.symbolicTraits
traits.insert(.traitBold)
if let fd = fontDescriptor.withSymbolicTraits(traits) {
return UIFont.init(descriptor: fd, size: 0)
}
}
return UIFont(descriptor: fontDescriptor, size: 0.0)
}
func with(font: UIFont) -> NSMutableAttributedString {
enumerateAttribute(NSAttributedString.Key.font, in: NSMakeRange(0, length), options: .longestEffectiveRangeNotRequired, using: { (value, range, stop) in
if let originalFont = value as? UIFont, let newFont = applyTraitsFromFont(originalFont, to: font) {
addAttribute(NSAttributedString.Key.font, value: newFont, range: range)
}
})
return self
}
private func applyTraitsFromFont(_ originalFont: UIFont, to newFont: UIFont) -> UIFont? {
let originalTrait = originalFont.fontDescriptor.symbolicTraits
if originalTrait.contains(.traitBold) {
var traits = newFont.fontDescriptor.symbolicTraits
traits.insert(.traitBold)
if let fontDescriptor = newFont.fontDescriptor.withSymbolicTraits(traits) {
return UIFont.init(descriptor: fontDescriptor, size: 0)
}
}
return newFont
}
}
用:
<yourUILabel>.set(html: "Hello, <b>world</b>!",
textAligment: NSTextAlignment.center)
我希望這可以幫助別人,
哈維
在我的例子中,我只需要使默認字體更大。 所以有解決方案。
- (NSAttributedString *)attributedStringFromHtml:(NSString *)htmlString largerFontBy:(CGFloat)pointSize fontColor:(UIColor *)fontColor
{
NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSDictionary *options = @{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
};
NSMutableAttributedString *mutableAttributedString = [[NSMutableAttributedString alloc] initWithData:data
options:options
documentAttributes:nil
error:nil];
[mutableAttributedString beginEditing];
[mutableAttributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, mutableAttributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL* stop)
{
if (value)
{
UIFont *oldFont = (UIFont*)value;
UIFontDescriptor* fontDescriptor = [oldFont.fontDescriptor fontDescriptorWithSymbolicTraits:oldFont.fontDescriptor.symbolicTraits];
UIFont *newFont = [UIFont fontWithDescriptor:fontDescriptor size:oldFont.pointSize + pointSize];
[mutableAttributedString removeAttribute:NSFontAttributeName range:range];
[mutableAttributedString addAttribute:NSFontAttributeName value:newFont range:range];
[mutableAttributedString addAttribute:NSForegroundColorAttributeName value:fontColor range:range];
}
}];
[mutableAttributedString endEditing];
return mutableAttributedString;
}
如果您需要更改字體,那會更難,因為您需要新字體來支持默認字體的所有traitsCollection
。 您可以嘗試使用UIFontDescriptor* fontDescriptor = [oldFont.fontDescriptor fontDescriptorWithSymbolicTraits:oldFont.fontDescriptor.symbolicTraits];
. 為您的新字體創建一個新的UIFontDescriptor
並使用此描述符和舊字體的特征創建字體。 在我的例子中,新字體是零,因為我沒有新字體的所有必要特征。 像粗體、斜體和等寬變體。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.