Swift:在标签或textView中显示HTML数据


83

我有一些HTML数据,其中包含标题,段落,图像和列表标签。

是否有一个显示该数据的方式UITextView还是UILabel


1
使用UIWebView代替UITextView或UILabel。因此它将显示包括图像
泰森·维格涅什

是的,我认为您是对的@TysonVignesh
Talha Ahmad Khan

@TysonVignesh如何使用UIWebView显示html?
穆罕默德·埃扎特

Answers:


206

对于Swift 5:

extension String {
    var htmlToAttributedString: 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 {
            return nil
        }
    }
    var htmlToString: String {
        return htmlToAttributedString?.string ?? ""
    }
}

然后,每当您要将HTML文本放入UITextView中时,请使用:

textView.attributedText = htmlText.htmlToAttributedString

6
这对我来说很棒,但是我不得不改用label.attributedText。
布伦特·瓦格纳

大!我只需要将东欧拉丁字母的编码数据更改为unicode。
NJA

大!但是调用时label.attributedText应该为label.text
Sazzad Hissain Khan

6
是否应该保留图像?
daredevil1234

1
@Roger Carvalho:有没有办法为包含的html标记设置字体系列,-size等?
Bernhard Engl

35

这是Swift 3版本:

private func getHtmlLabel(text: String) -> UILabel {
    let label = UILabel()
    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.attributedString = stringFromHtml(string: text)
    return label
}

private func stringFromHtml(string: String) -> NSAttributedString? {
    do {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
        if let d = data {
            let str = try NSAttributedString(data: d,
                                             options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
                                             documentAttributes: nil)
            return str
        }
    } catch {
    }
    return nil
}

我在这里找到其他一些答案的问题,花了我一些时间才能正确解决。我设置了换行模式和行数,以便当HTML跨多行时标签的大小适当。


HTML已解析...但是不正确。标记不再显示,但不显示粗体文本。我不知道支持哪些标签,也许<b>不支持。
Pablo

粗体标签对我来说很好用。您可以发布无法使用的完整html吗?可能是您使用的字体显示不佳。
加里

html只是来自CMS编辑器的文本,经过编码后返回JSON字符串。该应用访问Web服务,获取包含此特定文本对象的JSON-客户端的要求是,可以在文本中添加html标签,类似于网站的CMS(wordpress)。也许我对返回的编码不正确?当我解析JSON时,我将在调试时打印返回的字符串并正确显示,包括'<b> </ b>',但是在模拟器和用于测试的设备上,标记均无效。我正在使用Swift3。–
Pablo

3
如何添加自定义字体?
巴文·拉玛尼

14

添加此扩展名以将您的html代码转换为常规字符串:

    extension String {

        var html2AttributedString: NSAttributedString? {
            guard
                let data = dataUsingEncoding(NSUTF8StringEncoding)
            else { return nil }
            do {
                return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil)
            } catch let error as NSError {
                print(error.localizedDescription)
                return  nil
            }
        }
        var html2String: String {
            return html2AttributedString?.string ?? ""
        }
}

然后在UITextView或UILabel中显示String

textView.text = yourString.html2String 要么

label.text = yourString.html2String

1
是的,但是仅适用于HTML中的文本。我还担心图像和列表。有什么方法可以显示图像和列表是单个对象吗?
塔拉·艾哈迈德·汗

@TalhaAhmadKhan如果您有图片,则可以直接使用UIWebView。如您所知,TextView或标签将无法工作。
Sathe_Nagaraja

8

此后,我在更改文本属性时遇到问题,我可以看到其他人问为什么...

因此,最佳答案是将扩展名与NSMutableAttributedString结合使用:

extension String {

 var htmlToAttributedString: NSMutableAttributedString? {
    guard let data = data(using: .utf8) else { return nil }
    do {
        return try NSMutableAttributedString(data: data,
                                      options: [.documentType: NSMutableAttributedString.DocumentType.html,
                                                .characterEncoding: String.Encoding.utf8.rawValue],
                                      documentAttributes: nil)
    } catch let error as NSError {
        print(error.localizedDescription)
        return  nil
    }
 }

}

然后您可以通过以下方式使用它:

if let labelTextFormatted = text.htmlToAttributedString {
                let textAttributes = [
                    NSAttributedStringKey.foregroundColor: UIColor.white,
                    NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 13)
                    ] as [NSAttributedStringKey: Any]
                labelTextFormatted.addAttributes(textAttributes, range: NSRange(location: 0, length: labelTextFormatted.length))
                self.contentText.attributedText = labelTextFormatted
            }

我想达到相同的目的,但是上面的代码不起作用。
Pratyush Pratik,

7

斯威夫特3.0

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

6

我正在使用这个:

extension UILabel {
    func setHTML(html: String) {
        do {
            let attributedString: NSAttributedString = try NSAttributedString(data: html.data(using: .utf8)!, options: [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType], documentAttributes: nil)
            self.attributedText = attributedString
        } catch {
            self.text = html
        }
    }
}

1
这很好,但仅适用于UILabel。如果它是通用扩展名,它将采用html并转换为属性文本,那就更好了。
i.AsifNoor

4

迅捷3

extension String {


var html2AttributedString: NSAttributedString? {
    guard
        let data = data(using: String.Encoding.utf8)
        else { return nil }
    do {
        return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:String.Encoding.utf8], documentAttributes: nil)
    } catch let error as NSError {
        print(error.localizedDescription)
        return  nil
    }
}
var html2String: String {
    return html2AttributedString?.string ?? ""
 }
}

1
迅速3.1 NSCharacterEncodingDocumentAttribute:String.Encoding.utf8.rawValue
可以Aksoy

3

迅捷5

extension UIColor {
    var hexString: String {
        let components = cgColor.components
        let r: CGFloat = components?[0] ?? 0.0
        let g: CGFloat = components?[1] ?? 0.0
        let b: CGFloat = components?[2] ?? 0.0

        let hexString = String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)),
                               lroundf(Float(b * 255)))

        return hexString
    }
}
extension String {
    func htmlAttributed(family: String?, size: CGFloat, color: UIColor) -> NSAttributedString? {
        do {
            let htmlCSSString = "<style>" +
                "html *" +
                "{" +
                "font-size: \(size)pt !important;" +
                "color: #\(color.hexString) !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
        }
    }
}

最后,您可以创建UILabel:

func createHtmlLabel(with html: String) -> UILabel {
    let htmlMock = """
    <b>hello</b>, <i>world</i>
    """

    let descriprionLabel = UILabel()
    descriprionLabel.attributedText = htmlMock.htmlAttributed(family: "YourFontFamily", size: 15, color: .red)

    return descriprionLabel
}

结果:

在此处输入图片说明

参见教程:

https://medium.com/@valv0/a-swift-extension-for-string-and-html-8cfb7477a510


2

试试这个:

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 ""
    }

希望对您有所帮助。


是的,但是仅适用于HTML中的文本。我还担心图像和列表。有什么方法可以显示图像和列表是单个对象吗?
塔拉·艾哈迈德·汗

3
应当指出的是,使用NSHTMLTextDocumentType令人难以置信的慢[1]。尝试使用像DDHTML这样的库。[1] robpeck.com/2015/04/nshtmltextdocumenttype-is-slow-
克里斯托弗·凯文·豪威尔

2

上面的答案在这里是Swift 4.2


extension String {

    var htmlToAttributedString: NSAttributedString? {
        guard
            let data = self.data(using: .utf8)
            else { return nil }
        do {
            return try NSAttributedString(data: data, options: [
                NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
                NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue
                ], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
            return  nil
        }
    }

    var htmlToString: String {
        return htmlToAttributedString?.string ?? ""
    }
}

2

对于Swift 5,它也可以加载CSS。

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
        }
    }
}

之后,转到要转换为NSAttributedString的字符串,然后将其放置为以下示例:

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

在此处输入图片说明 这是每个参数采用的方法:

  • 字体:使用UIFont以及自定义字体的名称和大小,像通常在UILabel / UITextView中添加字体一样。
  • csscolor:要么以十六进制格式添加颜色,例如“#000000”,要么使用颜色名称,例如“黑色”。
  • lineheight:当UILabel / UITextView中有多行时,这是行之间的间隔。
  • csstextalign:这是文本的对齐方式,您需要添加的值是“ left”或“ right”或“ center”或“ justify”

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



1

无法显示图片和文字段落,UITextView或者UILabel,您必须使用UIWebView

只需将项目添加到情节提要中,链接到您的代码,然后调用它以加载URL。

OBJ-C

NSString *fullURL = @"http://conecode.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_viewWeb loadRequest:requestObj];

迅速

let url = NSURL (string: "http://www.sourcefreeze.com");
let requestObj = NSURLRequest(URL: url!);
viewWeb.loadRequest(requestObj);

分步教程。 http://sourcefreeze.com/uiwebview-example-using-swift-in-ios/


两者都有可能。字符串只需要正确编码即可
froggomad

1

迅捷5

extension String {
    func htmlAttributedString() -> NSAttributedString? {
        guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
        guard let html = try? NSMutableAttributedString(
            data: data,
            options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
            documentAttributes: nil) else { return nil }
        return html
    }
}

呼叫:

myLabel.attributedText = "myString".htmlAttributedString()

-1

如果您具有内含HTML代码的字符串,则可以使用:

extension String {
var utfData: Data? {
        return self.data(using: .utf8)
    }

    var htmlAttributedString: NSAttributedString? {
        guard let data = self.utfData 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
        }
    }

    var htmlString: String {
        return htmlAttributedString?.string ?? self 
    }
}

并以您的代码使用:

label.text = "something".htmlString
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.