You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSAttributedString忽略HTML标签内样式问题:保留TM上标6px字号并应用自定义字体

Solution for Preserving HTML Styles When Applying Custom Font to NSAttributedString

Hey there! I totally get where you're coming from—applying a global font but losing those tiny TM styles is super frustrating. Let's fix this step by step.

The Core Issue

When you call addAttributes([.font : font], range: NSMakeRange(0, mutable.length)), you're overwriting all existing font-related attributes across the entire string, including the 6px font size set by your <sup> tag. Instead, we need to only apply the custom font to parts of the string that don't already have their own font styling.

Step-by-Step Fix

Here's how you can preserve the HTML-derived styles while applying your custom font to the rest:

  1. First, parse your HTML into an NSMutableAttributedString as before

    let newText = "My new trade mark is MELLON<sup style=\"font-size:6px\">TM</sup> Corporation"
    guard let data = newText.data(using: .utf8) else { return }
    
    let attrString = try? NSMutableAttributedString(
        data: data,
        options: [
            NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
            NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue,
        ],
        documentAttributes: nil
    )
    
    guard let mutableAttrString = attrString else { return }
    
  2. Define your custom font

    let customFont = UIFont(name: "YourCustomFontName", size: 10)! // Replace with your font and size
    
  3. Traverse the string and apply font only where it's missing
    We'll use enumerateAttributes to check each segment of the string. For segments that don't have an existing .font attribute, we'll apply our custom font:

    mutableAttrString.enumerateAttributes(in: NSRange(location: 0, length: mutableAttrString.length), options: []) { attributes, range, stop in
        // Check if the segment already has a font attribute
        if attributes[.font] == nil {
            mutableAttrString.addAttribute(.font, value: customFont, range: range)
        }
        // Optional: Adjust baseline offset for better sup tag alignment (matches HTML's <sup> behavior)
        if let existingFont = attributes[.font] as? UIFont, existingFont.pointSize == 6 {
            mutableAttrString.addAttribute(.baselineOffset, value: 4, range: range) // Tweak value to fit your design
        }
    }
    
  4. Assign to your label

    label.attributedText = mutableAttrString
    

Why This Works

The enumerateAttributes method iterates through every contiguous segment of the string that has the same set of attributes. By checking if a segment already has a .font attribute, we avoid overwriting the styles from your <sup> tag. The optional baseline offset adjustment ensures the TM sits neatly above the text, just like HTML's <sup> intended.

Bonus: Extend to Other Attributes

If you also want to set global attributes like text color without overriding existing styles, you can reuse this pattern—just check if the target attribute exists before applying it to a segment.

内容的提问来源于stack exchange,提问作者busido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:34:03