如何在iOS标签中显示HTML格式的文本

47

我希望在IOS上的UILabel上显示格式化的HTML文本。

在Android中,有这样的api:.setText(Html.fromHtml(somestring))

如何在XML中从HTML格式的字符串资源设置TextView文本

我想知道在IOS上是否有相应的功能?

我找到了这个线程:

如何在iPhone上从API显示HTML文本?

但是它建议使用UIWebView。 我需要在每个表格单元格中显示格式化的HTML字符串,因此我认为每行有1个webview似乎有点重。

有其他替代方案吗?

谢谢。


OHAttributedLabel可能会对您有所帮助 https://github.com/AliSoftware/OHAttributedLabel - Huy Nghia
7个回答

57

Swift 3.0

do {
    let attrStr = try NSAttributedString(
        data: "<b><i>text</i></b>".data(using: String.Encoding.unicode, allowLossyConversion: true)!,
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil)
    label.attributedText = attrStr
} catch let error {

}

3
对我有用。在示例中可以自由使用“let”代替“var”。 - alasker
1
不应该使用 try!,因为可能会抛出异常。 - chengsam
@UmaMadhavi 什么样的HTML标签?因为并不是所有标签都兼容。 - ƒernando Valle
<b>你好</b> 类似于这个 - Uma Madhavi
你可以在顶部找到答案。¯_(ツ)_/¯ 数据:"<b><i>文本</i></b>" .data(..... - ƒernando Valle
显示剩余5条评论

50

对于 Swift 2.0

var attrStr = try! NSAttributedString(
        data: "<b><i>text</i></b>".dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!,
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil)
label.attributedText = attrStr

4
如何更改此字符串的文本颜色?是否可以改变颜色?我尝试添加NSForegroundColorAttributeName,但没有起作用。 - Priyansh
1
它是否也支持图片? - Zac
有没有人想到过如何更改字体颜色和字体?我尝试了两种方法,但似乎其他选项都不适用于该文档类型属性集。 - Programmer Unextraordinair

29

Swift 4

import UIKit
let htmlString = "<html><body> Some <b>html</b> string </body></html>"
// works even without <html><body> </body></html> tags, BTW 
let data = htmlString.data(using: String.Encoding.unicode)! // mind "!"
let attrStr = try? NSAttributedString( // do catch
    data: data,
    options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
    documentAttributes: nil)
// suppose we have an UILabel, but any element with NSAttributedString will do
label.attributedText = attrStr

附加说明:控制格式化字符串的字体

如果您想使用适当缩放(即相对于用户设置)的系统(或其他)字体,可以按照以下步骤操作。

let newFont = UIFontMetrics.default.scaledFont(for: UIFont.systemFont(ofSize: UIFont.systemFontSize)) // The same is possible for custom font.

let mattrStr = NSMutableAttributedString(attributedString: attrStr!)
mattrStr.beginEditing()
mattrStr.enumerateAttribute(.font, in: NSRange(location: 0, length: mattrStr.length), options: .longestEffectiveRangeNotRequired) { (value, range, _) in
    if let oFont = value as? UIFont, let newFontDescriptor = oFont.fontDescriptor.withFamily(newFont.familyName).withSymbolicTraits(oFont.fontDescriptor.symbolicTraits) {
        let nFont = UIFont(descriptor: newFontDescriptor, size: newFont.pointSize)
        mattrStr.removeAttribute(.font, range: range)
        mattrStr.addAttribute(.font, value: nFont, range: range)
    }
}
mattrStr.endEditing()
label.attributedText = mattrStr

这对我来说完美地解决了问题!但是,有没有一种方法可以让它获取应用程序中正在使用的字体,而无需为每个<H2>或<P>标签定义字体系列和大小?在我的情况下,我只是使用系统字体。 - jammyman34
很好的问题,@ammyman34。我尽最大努力提供全面的答案。 - Paul B
谢谢你,Paul!我真的很感激你的热心帮助。不幸的是,我无法让它工作。而且,当我添加了第二组代码后,Xcode告诉我只能在iOS11.0或更高版本中使用,并将其包装在If #available(iOS 11.0,*){ }条件中......当我构建它时,它仍在呈现我的HTML内容,但它没有捕捉到应用程序的字体系列样式,即SanFrancisco(即默认设置),而是显示为衬线字体,如Times。另外,不确定这是否重要,但我必须将所有内容放在viewDidLoad函数中,否则它将无法构建。 - jammyman34
有时在添加属性(.font,范围:范围)之前,可能需要删除属性(.font,范围:范围)。 iOS11兼容性可能需要UIFontMetrics要求。您可以手动计算先前版本的大小。 - Paul B

23
你可以尝试使用 attributed string(属性字符串):
var attrStr = NSAttributedString(
        data: "<b><i>text</i></b>".dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true),
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil,
        error: nil)
label.attributedText = attrStr

4
请注意,这种方法在iOS8上非常缓慢。 - gibo
谢谢!这太棒了!在这位开发者的经验中,在iOS 8上并不慢。 - Ruben Martinez Jr.
我收到了以下错误信息: 无法使用类型为'(data: NSData?, options: [String : String], documentAttributes: _, error: _)'的参数列表调用'NSAttributedString'的初始化程序 - Daniele B
它不适用于Swift 2.0。请参见新答案中的解决方案。 - Daniele B
出现错误:“没有更多上下文的情况下,表达式的类型是不明确的”。 - imjaydeep
我的字符串类似于“Hello <a href='#/userProfile/NA==\n/MQ==\n' target='_blank'>@mansuu</a>”。@connor - Mansuu....

1

Objective-C 版本:

   NSError *error = nil;
   NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:contentData
                                                    options:@{NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType}
                                                    documentAttributes:nil error:&error];

这只是上面答案的Objective-C转换。所有上面的答案都是正确的,参考了上面的答案


0

对我来说,Paul的答案起作用了。但是对于自定义字体,我不得不使用以下hack。

//Please take care of force unwrapping
let data = htmlString.data(using: String.Encoding.unicode)! 
        let mattrStr = try! NSMutableAttributedString(
            data: data,
            options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
            documentAttributes: nil)
        let normalFont = UIFontMetrics.default.scaledFont(for: UIFont(name: "NormalFontName", size: 15.0)!)//
        let boldFont = UIFontMetrics.default.scaledFont(for: UIFont(name: "BoldFontName", size: 15.0)!)
        mattrStr.beginEditing()
        mattrStr.enumerateAttribute(.font, in: NSRange(location: 0, length: mattrStr.length), options: .longestEffectiveRangeNotRequired) { (value, range, _) in
            if let oFont = value as? UIFont{
                mattrStr.removeAttribute(.font, range: range)
                if oFont.fontName.contains("Bold"){
                    mattrStr.addAttribute(.font, value: boldFont, range: range)
                }
                else{
                    mattrStr.addAttribute(.font, value: normalFont, range: range)
                }

            }
        }

-1
Try this:

let label : UILable! = String.stringFromHTML("html String")

func stringFromHTML( string: String?) -> String
    {
        do{
            let str = try NSAttributedString(data:string!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true
                )!, options:[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSNumber(unsignedLong: NSUTF8StringEncoding)], documentAttributes: nil)
            return str.string
        } catch
        {
            print("html error\n",error)
        }
        return ""
    }
Hope its helpful.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接