Search code examples
iosswiftnsattributedstring

attributed string issue in iOS 13


I am using below extension to convert HTML string to attributed string, to render the attributed string I am using UILabel. Font family is system-regular with points 15/18 for iPhone/iPad resp. In above Imgs, Description is the caption and attributed string is the value.

extension NSAttributedString {

    internal convenience init?(html: String, font : UIFont) {

        let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', '\(font.fontName)'; font-size: \(font.pointSize)\">%@</span>", html)

        guard let data = modifiedFont.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
            return nil
        }

        guard let attributedString = try? NSMutableAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) else {
            return nil
        }

        self.init(attributedString: attributedString)
    }
}

console print of variables in above extension

(lldb) po html
"<p><font size=\"2\">Pack Size: 2.5 Gal x 2</font></p><p><font size=\"2\">Gallons per case / bucket / barrel:</font></p><p><font size=\"2\">1 Case – 5.0 Gal<br>&nbsp;2 Cases – 10.0 Gal<br>&nbsp;3 Cases – 15.0 Gal</font></p>"

(lldb) po font
<UICTFont: 0x7ffbe4b03a20> font-family: ".SFUI-Regular"; font-weight: normal; font-style: normal; font-size: 15.00pt


(lldb) po modifiedFont
"<span style=\"font-family: \'-apple-system\', \'.SFUI-Regular\'; font-size: 15.0\"><p><font size=\"2\">Pack Size: 2.5 Gal x 2</font></p><p><font size=\"2\">Gallons per case / bucket / barrel:</font></p><p><font size=\"2\">1 Case – 5.0 Gal<br>&nbsp;2 Cases – 10.0 Gal<br>&nbsp;3 Cases – 15.0 Gal</font></p></span>"

I am calling extension like below

self.lblValueDescription.attributedText = NSAttributedString(html: data.descriptionField,
                                                                     font: self.lblValueDescription.font)

Output in iOS 12

enter image description here

Output in iOS 13

enter image description here

Issue:

  1. Font size is not same as expected in iOS12
  2. iOS13 have some alien characters with same html string.

Solution

  • Try this Solutions its working on Both ios 12 and 13 on my side may be its help you.

    extension String
    {
     func htmlAttributed(family: String?, size: CGFloat, colorHex: String) -> NSAttributedString?
      {
        do {
            let htmlCSSString = "<style>" +
                "html *" +
                "{" +
                "font-size: \(size)pt !important;" +
                 "color: " + "\(colorHex)" + " !important;" +
                "font-family: \(family ?? "Helvetica"), Helvetica !important;" +
            "}</style> \(self)"
    
            guard let data = htmlCSSString.data(using: String.Encoding.utf8) else {
                return nil
            }
    
            return try NSAttributedString(data: data,
                                          options: [.documentType: NSAttributedString.DocumentType.html,
                                                    .characterEncoding: String.Encoding.utf8.rawValue],
                                          documentAttributes: nil)
        } catch {
            print("error: ", error)
            return nil
        }
      }
    }
    

    And Set Text by this line

     self.lblValueDescription.attributedText = yourHtmlString.htmlAttributed(family: "Roboto-Regular", size: 11,colorHex: "#000000")!
    

    Edit:

    After Reviewing answer I made below changed

     let modifiedFont = String(format:"<style>html *{font-family: '-apple-system', '\(font.fontName)' !important; font-size: \(font.pointSize) !important}</style>%@", html)
    
    • Modify style tag with the style block
    • !important flag added to forcily applying the style.