【问题标题】:How to set custom font with regular and bold font while setting html string to label in swift 4?如何在swift 4中将html字符串设置为标签时使用常规和粗体字体设置自定义字体?
【发布时间】:2019-10-06 10:54:41
【问题描述】:

我从API 响应中获得HTML 格式化字符串,因此我需要将其设置为标签,同时保持自定义字体(对于我的应用程序)并应用样式(粗体、常规等)标签。

我使用了一个扩展,可以将HTML 字符串转换为带有换行符等的常规字符串。但是,我可以在此处设置字体,但只有一种字体并且它仅以常规字体显示,所以整个标签是一种字体,我想要的是将粗体字体设置为粗体 HTML 部分,将常规字体设置为常规 HTML 部分/标签。

extension String {
    var htmlToAttributedString: NSAttributedString {
        guard let data = data(using: .utf8) else { return NSAttributedString() }
        do {
            return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch {
            return NSAttributedString()
        }
    }
    var htmlToString: String {
        return htmlToAttributedString.string
    }
}

//set converted html to string here
let whyAttendAttributedText: NSMutableAttributedString = NSMutableAttributedString(attributedString: attendData.whyAttendData?.desc?.htmlToAttributedString ?? NSAttributedString())

//set font here   
whyAttendAttributedText.addAttributes([NSMutableAttributedString.Key.font: CommonSettings.shared.getFont(type: .regular, size: descriptionLabel.font.pointSize), NSMutableAttributedString.Key.foregroundColor: UIColor.white], range: NSMakeRange(0, whyAttendAttributedText.length))

我想给文本设置粗体和常规字体,但由于我只设置了一种字体,我无法得到结果,有没有办法像HTML字符串一样设置粗体和常规字体?

【问题讨论】:

    标签: ios objective-c swift uilabel swift4


    【解决方案1】:

    这应该会有所帮助:

    extension String {
    
    func attributedString(withRegularFont regularFont: UIFont, andBoldFont boldFont: UIFont) -> NSMutableAttributedString {
        var attributedString = NSMutableAttributedString()
            guard let data = self.data(using: .utf8) else { return NSMutableAttributedString() }
            do {
                attributedString = try NSMutableAttributedString(data: data,
                                                                 options: [.documentType: NSAttributedString.DocumentType.html,
                                                                           .characterEncoding:String.Encoding.utf8.rawValue],
                                                                 documentAttributes: nil)
                let range = NSRange(location: 0, length: attributedString.length)
                attributedString.enumerateAttribute(NSAttributedString.Key.font, in: range, options: .longestEffectiveRangeNotRequired) { value, range, _ in
                    let currentFont: UIFont         = value as! UIFont
                    var replacementFont: UIFont?    = nil
    
                    if currentFont.fontName.contains("bold") || currentFont.fontName.contains("Bold") {
                        replacementFont             =   boldFont
                    } else {
                        replacementFont             =   regularFont
                    }
    
                    let replacementAttribute        =   [NSAttributedString.Key.font:replacementFont!]
                    attributedString.addAttributes(replacementAttribute, range: range)
                }
            } catch let e {
                print(e.localizedDescription)
            }
           return attributedString
    }
    }
    

    【讨论】:

    • 成功了!!!非常感谢你。它给出了一些错误,我刚刚编辑了它,请批准
    【解决方案2】:

    可以使用以下方法将粗体和其他不同样式应用于文本。

    extension String {
    
        func attributedString(with style: [NSAttributedString.Key: Any]? = nil,
                              and highlightedText: String,
                              with highlightedTextStyle: [NSAttributedString.Key: Any]? = nil) -> NSAttributedString {
    
            let formattedString = NSMutableAttributedString(string: self, attributes: style)
            let highlightedTextRange: NSRange = (self as NSString).range(of: highlightedText as String)
            formattedString.setAttributes(highlightedTextStyle, range: highlightedTextRange)
            return formattedString
        }
    }
    

    输入:“这是一条测试消息”

    预期输出:“这是一个测试消息”

    这可以通过以下方式实现。

    let sampleInput = "This is a test message"
    let boldtext = "test"
    
    let output = sampleInput.attributedString(with: [.font: UIFont.systemFont(ofSize: 12.0, weight: .regular)],
                                 and: boldtext, with: UIFont.systemFont(ofSize: 12.0, weight: .bold))
    

    可以使用不同的属性键应用不同的样式。希望这会有所帮助。

    【讨论】:

    • 对不起,没用,我不知道什么是粗体文本,我只有一个包含粗体标签和常规文本的字符串
    【解决方案3】:

    假设你在解析 HTML 字符串后的字符串是:"This is your HTML string"

    创建attributed string

    let attrStr = NSMutableAttributedString(string: "This is your HTML string")
    

    添加UIFont属性,值为System-Regular

    attrStr.addAttribute(.font, value: UIFont.systemFont(ofSize: 14.0, weight: .regular), range: NSRange(location: 0, length: attrStr.length))
    

    每当向attributed string 添加attribute 时,我们需要提供stringrange,我们希望在其中反映attribute

    由于我们需要整个string 具有Regular 字体,所以range 被计算为整个string length

    现在,将值为System-BoldUIFont 属性添加到string 的一部分,假设我们将HTML 设为粗体,

    attrStr.addAttribute(.font, value: UIFont.systemFont(ofSize: 14.0, weight: .bold), range: (attrStr.string as NSString).range(of: "HTML"))
    

    我们已经计算了整个字符串中 HTML 单词的range

    同样,您可以将任何 attributes 添加到 string 以提供相关的 range 值。

    输出:This is yourHTMLstring

    Edit-1:

    要计算<b> to </b>range,您需要手动计算。

    示例:

    let str = "This <b>is your HTML</b> string"
    let range1 = (str as NSString).range(of: "<b>")
    let range2 = (str as NSString).range(of: "</b>")
    let requiredRange = NSRange(location: range1.location, length: range2.location + range2.length - range1.location)
    

    上述示例适用于string&lt;b&gt;/&lt;/b&gt; 的单个实例。

    Edit-2:

    string 包含多个&lt;b&gt;/&lt;/b&gt; 实例时:

    let htmlStr = "This is an <b>HTML</b> parsed <b>string</b>"
    let arr = htmlStr.components(separatedBy: "</b>")
    let attrStr = NSMutableAttributedString()
    for str in arr {
        if !str.isEmpty {
            let range1 = (str as NSString).range(of: "<b>")
            let requiredRange = NSRange(location: range1.location, length: str.count - range1.location)
    
            let formattedStr = NSMutableAttributedString(string: str)
            formattedStr.addAttribute(.font, value: UIFont.systemFont(ofSize: 14.0, weight: .bold), range: requiredRange)
            attrStr.append(formattedStr)
            attrStr.append(NSAttributedString.init(string: "</b>", attributes: [.font : UIFont.systemFont(ofSize: 14.0, weight: .bold)]))
        }
    }
    self.label.attributedText = attrStr
    

    输出:This is an&lt;b&gt;HTML&lt;/b&gt;parsed&lt;b&gt;string&lt;/b&gt;

    【讨论】:

    • 有没有办法计算字符串中 的范围?并应用上述逻辑
    • 字符串是否包含的单个实例?
    • 不,它可能包含许多标签,非常感谢您的更新
    • 更新了多实例的代码。试一试,看看它是否工作正常。
    猜你喜欢
    • 2021-07-06
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多