htmlswiftstringnsattributedstringnsmutableattributedstring

NSAttributedString ignores properties inside html tag


Word "TM" needs to be font-size 6px.

let newText = "My new trade mark is MELLON<sup style="font-size:6px">TM</sup> Corporation"

What I do, I convert it to AttributedString:

let htmlToNSAttributedString = NSAttributedString(data: self, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)

And it goes well: before custom font

(when the font size is 10, it matches default size of NSAtrString)

I have to match this text with design and added customized font to it:

mutable.addAttributes([.font : font], range: NSMakeRange(0, mutable.length))

And get next result: after custom font

So the custom font and its size overrides the style properties of tag.

How do I keep them?

For example, I have this to work with: printed attributed String

Can I retract data for exact parts of NSAttributedStr? So I can store it and then add parts back together?

EDIT

Added some more code for reference

let newText = "My new trade mark is MELLON<sup style=\"font-size:6px\">TM</sup> Corporation"
    let data = newText.data(using: .utf8)
    let attrString = try? NSMutableAttributedString(
        data: data ?? Data(),
        options: [
                  NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,

    NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue,
                    ],
        documentAttributes: nil
    )
    let mainAttributedText = NSMutableAttributedString()

    mainAttributedText.append(attrString ?? NSMutableAttributedString())
    label.textStorage?.append(mainAttributedText)

Solution

  • @Larm gave good idea to fixing this:

    iterate over your attributes, and replace the font (with the new one but with the current font size).

    So this what I did:

    mutable.enumerateAttributes(in: NSMakeRange(0, mutable.length), options: .longestEffectiveRangeNotRequired) { attrs, range, stop in
                if (attrs[.superscript] == nil) {
                    mutable.addAttributes([.font : font], range: range)
                } else {
                    let oldFont = attrs[.font] as? NSFont ?? font
                    mutable.addAttributes([.font : NSFont(name: font.fontName, size: oldFont.pointSize) ?? font], range: range)
                }
            }
    
        }
    

    I checked if attr had property ofNSSuperScript which corresponds with tag <sup> And if so I skipped setting font size to it, but instead applied only new font style

    Note: Have still some issues with Title thing, but in description everything is good

    New layout

    When I fix it I will edit this answer