ios 当我把HTML翻译成NSAttributedString时,我可以设置默认字体吗?

5kgi1eie  于 2022-12-20  发布在  iOS
关注(0)|答案(4)|浏览(164)

我尝试在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**";
}

似乎字体大小:12.00pt是默认大小,我想在不修改HTML源代码的情况下修改大小。怎么做?

xtfmy6hx

xtfmy6hx1#

你可以通过一点编码来完成它...你需要遍历属性,并改变属性化字符串的每一段的字体大小(如正常、斜体、粗体等)。

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)!)
oogrdqng

oogrdqng2#

下面是@Maria的NSMutableAttributedString扩展名在Swift 5.1中的重写

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
    }
}
kcwpcxri

kcwpcxri3#

这是我的版本,支持文本样式(正文、标题等)、文本对齐,可直接在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)

我希望这能帮上忙,
哈维

bvk5enib

bvk5enib4#

目标语言-C

在我的情况下,我只需要使默认字体变大。所以有解决方案。

- (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的新字体,并创建字体与此描述符和特点的旧字体。在我的情况下,新字体是零,因为我没有所有必要的特点,为新字体。如粗体,斜体和等宽变体。

相关问题