0

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)
busido
  • 13
  • 5
  • Because you re replacing the font for the WHOLE `NSAttributedString`, but `UIFont` is not only a font name, it has also the size property, to you set a font size for the whole attributed string, that's why. Instead, iterate over your attributes, and replace the font (with the new one but with the current font size). – Larme Jun 29 '21 at 14:31
  • @Larme thank you for swift :) answer! I will try that. I have looked at that question, but didn't quit got the idea of it, but now it is more clear where I have to look. thanks again – busido Jun 29 '21 at 14:34

1 Answers1

0

@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

busido
  • 13
  • 5
  • Unrelated, but `NSAttributedString.Key(rawValue: "NSSuperScript")` that should be `NSAttributedString.Key.superscript`, and since you know the key type, you can just write `attrs[.superscript]`. Same for `NSFont` which is `NSAttributedString.Key.font` – Larme Jun 29 '21 at 15:55
  • But shouldn't you apply the `oldFont` and `newFont` code even if superscripted? Then you change correctly the font family, and keep the initial size... – Larme Jun 29 '21 at 15:57
  • @Larm if I correctly got your question, I am doing this in `else` statement (when it is not superscripted) – busido Jun 29 '21 at 16:23
  • `mutable.enumerateAttribute(.font, in: NSRange(location: 0, length: mutable.length), options: []) { value, range, stop in let replacementFont = UIFont(name: newFont.fontName, size: (value as? UIFont)?.pointSize ?? newFont.pointSize); mutable.addAttribute(.font, value: replacementFont, range: range)}` should do the trick. – Larme Jun 29 '21 at 16:25
  • @Larme thanks for nice refactor! – busido Jun 29 '21 at 16:39