使用旧金山字体将HTML解析为NSAttributedString? (iOS 9)

时间:2015-10-28 04:05:03

标签: ios ios9 accessibility nsattributedstring uifont

我需要解析包含<b>(粗体),<i>(斜体)和<u>(下划线)标签的基本HTML字符串,不需要其他任何东西,只需要那些简单的标签。

现在,在<u>中使用新的NSAttributedString时,我只能在San Francisco中正确呈现iOS 9(下划线)标记。

我真的需要得到<b>(粗体)和<i>(斜体)来渲染。

这就是我正在做的事情:

let text = "<i>Any</i> <b>Text</b> <u>that's 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)

但遗憾的是,<i>(斜体)和<b>(粗体)标记从不呈现,只有<u>(下划线)呈现正确。

此同样的方法用于使用iOS 8字体处理Helvetica-Neue,但它不能使用新的iOS 9 San Francisco字体

帮助我<b>(粗体)和<i>(斜体)在NSAttributedString中正确呈现!

更新:我也在整个应用程序中使用动态文本。这可能是导致事情无法正常工作的原因......

1 个答案:

答案 0 :(得分:4)

在应用中同时使用NSAttributedStringDynamicType是造成问题的原因。

事实证明,需要在收到String后重新解析/呈现您的UIContentSizeCategoryDidChangeNotification。您无法保留NSAttributedString,然后使用它来重置UILabel中的文字。您必须重新解析/呈现NSAttributedString

简要示例:

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's 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)
}