【问题标题】:Swift: Display HTML data in a label or textView [duplicate]Swift:在标签或文本视图中显示 HTML 数据 [重复]
【发布时间】:2016-08-31 03:11:19
【问题描述】:

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

有没有办法在UITextViewUILabel 中显示这些数据?

【问题讨论】:

  • 使用 UIWebView 代替 UITextView 或 UILabel。所以它会显示包括图像
  • 是的,我认为你是对的@TysonVignesh
  • @TysonVignesh 如何使用 UIWebView 显示 html ?
  • @MohamedEzzat 看到这个链接hackingwithswift.com/example-code/uikit/…

标签: html ios swift uitextview nsattributedstring


【解决方案1】:

对于 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

【讨论】:

  • 这对我很有用,但我不得不改用 label.attributedText。
  • 这应该保留图像吗?
  • @Roger Carvalho:有没有办法为包含的 html 标签设置 font-family、-size 等?
  • hypens 显示为“有没有办法解决这个问题?
  • @MartinzChukz 在选项中添加这个.characterEncoding: String.Encoding.utf8.rawValue
【解决方案2】:

这是一个 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>不支持。
  • 粗体标签对我来说很好用。您可以发布不起作用的完整 html 吗?可能您使用的字体显示不好。
  • html 只是来自 CMS 编辑器的文本,经过编码以返回 JSON 字符串。应用程序访问 Web 服务,获取包含此特定文本对象的 JSON - 此处客户端的要求是向文本添加 html 标记的可能性,类似于网站的 CMS(wordpress)。也许我对返回的编码不正确?当我解析 JSON 时,我在调试时打印字符串返回并正确显示,包括“”,但在模拟器和测试设备上,标签都不起作用。我正在使用 Swift 3。
  • 如何添加自定义字体?
【解决方案3】:

添加此扩展以将您的 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 中显示你的字符串

textView.text = yourString.html2String

label.text = yourString.html2String

【讨论】:

  • 是的,但它只适用于 HTML 中的文本。我还担心图像和列表。有没有办法显示图像和列表是单个对象??
  • @TalhaAhmadKhan 如果您有图像,您可以直接使用 UIWebView。如您所知,TextView 或标签将无法正常工作。
【解决方案4】:

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

所以最好的答案是使用带有 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
            }

【讨论】:

  • 我想达到同样的效果,但上面的代码不起作用。
【解决方案5】:

对于 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")

以下是每个参数的含义:

  • 字体:像往常一样在 UILabel/UITextView 中添加字体,使用带有自定义字体名称和大小的 UIFont。
  • csscolor:以 HEX 格式添加颜色,如“#000000”或使用颜色名称,如“black”。
  • 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/

【讨论】:

    【解决方案6】:

    斯威夫特 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
    

    【讨论】:

      【解决方案7】:

      斯威夫特 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

      【讨论】:

        【解决方案8】:

        我正在使用这个:

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

        【讨论】:

        • 这很好,但只适用于 UILabel。如果它是通用扩展,它应该采用 html 并转换为属性文本,那就更好了。
        【解决方案9】:

        斯威夫特 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 ?? ""
         }
        }
        

        【讨论】:

        • swift 3.1 NSCharacterEncodingDocumentAttribute:String.Encoding.utf8.rawValue
        【解决方案10】:

        这里的上述答案是 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 ?? ""
            }
        }
        

        【讨论】:

          【解决方案11】:

          试试这个:

          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 中的文本。我还担心图像和列表。有没有办法显示图像和列表是单个对象??
          • 应该注意的是,使用NSHTMLTextDocumentType难以置信慢 [1]。尝试改用 DDHTML 之类的库。 [1]robpeck.com/2015/04/nshtmltextdocumenttype-is-slow
          【解决方案12】:
          extension UITextView {
              func setHTMLFromString(htmlText: String) {
                  let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>", htmlText)
          
                  let attrStr = try! NSAttributedString(
                      data: modifiedFont.data(using: .utf8, allowLossyConversion: true)!,
                      options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue],
                      documentAttributes: nil)
          
                  self.attributedText = attrStr
              }
          }
          

          【讨论】:

            【解决方案13】:

            如果你想要 HTML,带有图像和列表,UILabel 不支持。但是,我发现 YYText 可以解决问题。

            【讨论】:

            • 正确编码字符串时支持。有一个用于 HTML 的属性字符串扩展在某处浮动
            【解决方案14】:

            UITextViewUILabel 中无法显示图像和文本段落,对此,您必须使用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/

            【讨论】:

            • 两者都有可能。字符串只需要正确编码
            【解决方案15】:

            斯威夫特 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()
            

            【讨论】:

              【解决方案16】:

              我知道这看起来有点过头了,但是...... 这段代码将为 UILabel、UITextView、UIButton 添加 html 支持并且您可以轻松地将这种支持添加到任何视图已归因字符串支持:

              public protocol CSHasAttributedTextProtocol: AnyObject {
                  func attributedText() -> NSAttributedString?
                  func attributed(text: NSAttributedString?) -> Self
              }
              
              extension UIButton: CSHasAttributedTextProtocol {
                  public func attributedText() -> NSAttributedString? {
                      attributedTitle(for: .normal)
                  }
              
                  public func attributed(text: NSAttributedString?) -> Self {
                      setAttributedTitle(text, for: .normal); return self
                  }
              }
              
              extension UITextView: CSHasAttributedTextProtocol {
                  public func attributedText() -> NSAttributedString? { attributedText }
              
                  public func attributed(text: NSAttributedString?) -> Self { attributedText = text; return self }
              }
              
              extension UILabel: CSHasAttributedTextProtocol {
                  public func attributedText() -> NSAttributedString? { attributedText }
              
                  public func attributed(text: NSAttributedString?) -> Self { attributedText = text; return self }
              }
              
              public extension CSHasAttributedTextProtocol
                      where Self: CSHasFontProtocol, Self: CSHasTextColorProtocol {
                  @discardableResult
                  func html(_ text: String) -> Self { html(text: text) }
              
                  @discardableResult
                  func html(text: String) -> Self {
                      let html = """
                                 <html><body style="color:\(textColor!.hexValue()!); 
                                              font-family:\(font()!.fontName); 
                                              font-size:\(font()!.pointSize);">\(text)</body></html>
                                 """
                      html.data(using: .unicode, allowLossyConversion: true).notNil { data in
                          attributed(text: try? NSAttributedString(data: data, options: [
                              .documentType: NSAttributedString.DocumentType.html,
                              .characterEncoding: NSNumber(value: String.Encoding.utf8.rawValue)
                          ], documentAttributes: nil))
                      }
                      return self
                  }
              }
              
              
              public protocol CSHasFontProtocol: AnyObject {
                  func font() -> UIFont?
                  func font(_ font: UIFont?) -> Self
              }
              
              extension UIButton: CSHasFontProtocol {
                  public func font() -> UIFont? { titleLabel?.font }
              
                  public func font(_ font: UIFont?) -> Self { titleLabel?.font = font; return self }
              }
              
              extension UITextView: CSHasFontProtocol {
                  public func font() -> UIFont? { font }
              
                  public func font(_ font: UIFont?) -> Self { self.font = font; return self }
              }
              
              extension UILabel: CSHasFontProtocol {
                  public func font() -> UIFont? { font }
              
                  public func font(_ font: UIFont?) -> Self { self.font = font; return self }
              }
              
              public protocol CSHasTextColorProtocol: AnyObject {
                  func textColor() -> UIColor?
                  func text(color: UIColor?) -> Self
              }
              
              extension UIButton: CSHasTextColorProtocol {
                  public func textColor() -> UIColor? { titleColor(for: .normal) }
              
                  public func text(color: UIColor?) -> Self { setTitleColor(color, for: .normal); return self }
              }
              
              extension UITextView: CSHasTextColorProtocol {
                  public func textColor() -> UIColor? { textColor }
              
                  public func text(color: UIColor?) -> Self { textColor = color; return self }
              }
              
              extension UILabel: CSHasTextColorProtocol {
                  public func textColor() -> UIColor? { textColor }
              
                  public func text(color: UIColor?) -> Self { textColor = color; return self }
              }
              

              【讨论】:

                【解决方案17】:

                如果您有一个包含 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
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-10-12
                  • 2015-12-27
                  • 2023-03-13
                  • 2020-02-20
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多