0

I am trying to display RichText that comes in was HTML in my SwiftUI app. Following the instructions here with Hacking With Swift for parsing that HTML into a NSAttributedString.

This works great, except that when it get parsed into an attributed string it automatically gets TimesNewRoman and translates into 12pt.

I would like to make a few changes to it so that when it is displayed in my app it looks like it belongs:

  1. Give it default system font.
  2. Scale it up slightly. Body font is 14pt in our app.
  3. Make it our text color.

So I embarked on making those changes which lead me to this wonderful solution listed here on Stack Overflow.

The problem is their solution relies on a bit of code where you need to run this line currentFont.fontDescriptor.addingAttributes([.family: "<Family Name>"])

First thing I tried was "San Francisco" but this did not work. I then used this other stack overflow post to get a list of font families. Unfortunately none of those families listed are San Francisco.

I then checked what this value was UIFont.systemFont(ofSize: 12, weight: .regular) curiously this returns a more primitive <UICTFont: 0x10900c7c0> font-family: ".SFUI-Regular"; font-weight: normal; font-style: normal; font-size: 20.00pt> object and if you ask it its .familyName you get .AppleSystemUIFont.

I tried plugging this all in with no luck. Here is the code I am trying and what it outputs to each step. It fails at the first if let.

That being said perhaps this is a sign to look at SwiftUI only solutions to this. As it would be nice to be able to modify the font from just regular SwiftUI modifiers. However I think since this attributed string has a font built in and the size/weight aspects of sections of the string are a part of a font I might be out of luck?

    // https://www.hackingwithswift.com/example-code/system/how-to-convert-html-to-an-nsattributedstring
    let data = Data(html.utf8)
    if let rawAttributedString = try? NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
        let newAttributedString = rawAttributedString
        // https://stackoverflow.com/a/42319336/3833632
        newAttributedString.enumerateAttribute(.font, in: NSMakeRange(0, newAttributedString.length), options: []) { value, range, stop in
            guard let currentFont = value as? UIFont else {
                return
            }
            let fontDescriptor = currentFont.fontDescriptor.addingAttributes([.family: ".AppleSystemUIFont", .name: ".SFUI-Regular"])
            /*
            UICTFontDescriptor <0x60000260edc0> = {
                NSCTFontVariationAttribute =     {
                    1869640570 = 12;
                    2003265652 = 400;
                    1936486004 = 0;
                    2003072104 = 100;
                };
                NSFontFamilyAttribute = ".AppleSystemUIFont";
                NSFontNameAttribute = ".SFUI-Regular";
                NSFontSizeAttribute = 12;
            }*/
            if let newFontDescriptor = fontDescriptor.matchingFontDescriptors(withMandatoryKeys: [.family]).first {
                // never gets here
                let newFont = UIFont(descriptor: newFontDescriptor, size: currentFont.pointSize * (14.0 / 12.0))
                newAttributedString.addAttributes([.font: newFont], range: range)
            }
        }
    }
2
  • It have baseURL parameter, you can provide css through it. Commented Feb 5 at 7:52
  • San Francisco is the default system font, but it is only available as a named font on watchOS, see iosfonts.com. Commented Feb 5 at 8:43

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.