在UITextView显示HTML,以及NSAttributedString乱码问题解决 swift

说明

当你要显示html到UILabel,UITextView的时候,需要把html字符串,转换为NSAttributedString.

最好情况下,加个String的extension。

extension String {
    public var convertHtmlToNSAttributedString: NSAttributedString? {
        guard let data = data(using: .utf8) else {
            return nil
        }
        do {
            return try NSAttributedString(data: data,options: [.documentType: NSAttributedString.DocumentType.html,.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }
        catch {
            print(error.localizedDescription)
            return nil
        }
    }
    
    public func convertHtmlToAttributedStringWithCSS(font: UIFont? , csscolor: String , lineheight: Int, csstextalign: String) -> NSAttributedString? {
        guard let font = font else {
            return convertHtmlToNSAttributedString
        }
        let modifiedString = "<style>body{font-family: '\(font.fontName)'; font-size:\(font.pointSize)px; color: \(csscolor); line-height: \(lineheight)px; text-align: \(csstextalign); }</style>\(self)";
        guard let data = modifiedString.data(using: .utf8) else {
            return nil
        }
        do {
            return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }
        catch {
            print(error)
            return nil
        }
    }
}

调用如下:

myUILabel.attributedText = "Swift is awesome&#33;&#33;&#33;".convertHtmlToAttributedStringWithCSS(font: UIFont(name: "Arial", size: 16), csscolor: "black", lineheight: 5, csstextalign: "center")

乱码问题

如果只是运用上面代码,没有发现问题。因为string的编码,和NSAttributeString的编码是一样的。下面举个乱码的例子。

let htmlString = """
    <html><head><style type=\"text/css\">body { font-family: Mehr Nastaliq Web; font-size: 22pt; white-space: pre-wrap; text-align: right; lang: en; direction: RTL; -webkit-user-select: none; meta charset=\"UTF-8\" }</style> </head><body leftmargin=\"20\" topmargin=\"0\" rightmargin=\"20\"> hello world! Arabic.<br/> مُدّعا عَنقا ہے اپنے عالَمِ تقریر کا میری تقریر کا مفہوم چونکہ عنقا یعنی معدوم ہے اور معدوم </body></html>
    """

    let attributedString = try? NSAttributedString(data:
        htmlString.data(using: String.Encoding.utf8)!, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
    textView.attributedText = attributedString

显示效果如下:
在这里插入图片描述

如果把NSAttributedString的编码去掉以后,修改的变量attributedString如下。

let attributedString = try? NSAttributedString(data:
            htmlString.data(using: String.Encoding.utf8)!, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)

就会显示乱码
在这里插入图片描述
如果同时修改字符串编码和NSAttributedString的编码为unicode, 结果也是正常的。读者可自行验证。

let attributedString = try? NSAttributedString(data:
                   htmlString.data(using: String.Encoding.unicode)!, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding:String.Encoding.unicode.rawValue], documentAttributes: nil)

需要了解字符编码:请参考文章 > 关于字符编码,你所需要知道的(ASCII,Unicode,Utf-8,GB2312…)

代码下载

https://gist.github.com/zgpeace/24ee9264e83c984f00191091d7b632ae

参考

https://stackoverflow.com/questions/50363326/nsrangeexception-reason-nsbigmutablestring-characteratindex-index/61133696#61133696

https://johncodeos.com/how-to-display-html-in-uitextview-uilabel-with-custom-color-font-etc-in-ios-using-swift/

扫描二维码关注公众号,回复: 10733462 查看本文章
发布了167 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zgpeace/article/details/105430035