Parse HTML in NSAttributedString with San Francisco Font? (iOS 9)

I need to parse the main HTML strings containing <b> (bold), <i> (italics) and <u> (underline) tags, nothing else, just those simple tags.

At the moment, I can get <u> (underscore) tags to display correctly in NSAttributedString when using the new San Francisco in iOS 9 .

I really need to get <b> (bold) and <i> (italics) for rendering.

That's what I'm doing:

 let text = "<i>Any</i> <b>Text</b> <u>that basic HTML</u>" let font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) let modifiedFont = NSString(format:"<span style=\"font-family: '-apple-system','HelveticaNeue'; font-size: %f \">%@</span>", font.pointSize, text) as String let data = (modifiedFont as NSString).dataUsingEncoding(NSUTF8StringEncoding) let attributedString = try? NSAttributedString(data: data!, options: [ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute : NSUTF8StringEncoding, NSFontAttributeName : font ], documentAttributes: nil) 

But, unfortunately, the <i> (italics) and <b> (bold) tags are never displayed, only the <u> (underscore) is displayed correctly.

The same exact method used to work with iOS 8 with the Helvetica-Neue font, but it does not work with the new iOS 9 San Francisco font

Help me get <b> (bold) and <i> (italics) to display correctly in NSAttributedString !

Update . I use dynamic text throughout the application. This may be the reason why everything is not working ...

+5
source share
1 answer

Using NSAttributedString and DynamicType in the application is what caused the problem.

As it turns out, you NEED reanalyzed / rendered your String after receiving UIContentSizeCategoryDidChangeNotification . You CANNOT save NSAttributedString and then use it to reset text in UILabel . You must re-parse / display the NSAttributedString .

Short description:

 public override func viewDidLoad() { super.viewDidLoad() //register be notified when text size changes. NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("didChangePreferredContentSize:"), name: UIContentSizeCategoryDidChangeNotification, object: nil) } // The action Selector that gets called after the text size has been changed. func didChangePreferredContentSize(notification: NSNotification) { self.myLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline) // // DO NOT do this: // self.myLabel.attributedText = self.myAlreadyRenderedText // //Make sure you re-render/parse the text into a new NSAttributedString. //Do THIS instead: self.myLabel.attributedText = self.renderAttributedText(str) } //Our method to render/parse the HTML tags in our text. Returns an NSAttributedString. func renderAttributedText(str: String) -> NSAttributedString? { let text = "<i>Any</i> <b>Text</b> <u>that basic HTML</u>" let font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) let modifiedFont = NSString(format:"<span style=\"font-family: '-apple-system','HelveticaNeue'; font-size: %f \">%@</span>",font.pointSize, text) as String let data = (modifiedFont as NSString).dataUsingEncoding(NSUTF8StringEncoding) let attributedString = try? NSAttributedString(data: data!, options: [ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute : NSUTF8StringEncoding, NSFontAttributeName : font ], documentAttributes: nil) return attributedString } deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } 
+3
source

Source: https://habr.com/ru/post/1234659/


All Articles