Swift : 레이블 또는 textView에 HTML 데이터 표시


86

제목, 단락, 이미지 및 목록 태그가 포함 된 HTML 데이터가 있습니다.

이 데이터를 하나 UITextView또는 하나에 표시하는 방법이 UILabel있습니까?


1
UITextView 또는 UILabel 대신 UIWebView를 사용하십시오. 이 이미지를 포함하여 표시됩니다 그래서
타이슨 인 Vignesh에게

네, 당신이 옳다고 생각합니다 @TysonVignesh
Talha Ahmad Khan

@TysonVignesh UIWebView를 사용하여 html을 표시하려면 어떻게해야합니까?
Mohamed Ezzat

답변:


215

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

그런 다음 UITextView에 HTML 텍스트를 넣고 싶을 때마다 다음을 사용하십시오.

textView.attributedText = htmlText.htmlToAttributedString

6
이것은 나를 위해 잘 작동했지만 대신 label.attributedText를 사용해야했습니다.
Brent Wagoner

큰! 동유럽 라틴 문자의 경우 인코딩 데이터를 유니 코드로 변경해야했습니다.
nja

큰! 하지만 label.attributedText는 호출 할 때 label.text 여야합니다
Sazzad Hissain Khan

6
이것은 이미지를 보존해야 하는가?
daredevil1234

1
@Roger Carvalho : 포함 된 html 태그에 대해 font-family, -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을 게시 할 수 있습니까? 사용중인 글꼴이 굵게 표시되지 않을 수 있습니다.
garie

html은 JSON 문자열로 반환되도록 인코딩 된 CMS 편집기의 텍스트입니다. 앱은 웹 서비스에 액세스하고이 특정 텍스트 개체를 포함하는 JSON을 가져옵니다. 클라이언트의 요구 사항은 웹 사이트의 CMS (wordpress)와 유사하게 텍스트에 html 태그를 추가 할 수 있다는 것입니다. 반환을 잘못 인코딩하고 있습니까? JSON을 구문 분석 할 때 디버그에서 문자열 반환을 인쇄하고 '<b> </ b>'를 포함하여 올바르게 표시되지만 테스트 용 에뮬레이터와 장치 모두에서 태그가 작동하지 않습니다. 저는 Swift 3을 사용하고 있습니다.
Pablo

3
사용자 정의 글꼴을 추가하려면 어떻게합니까?
Bhavin Ramani

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 안에 문자열을 표시합니다.

textView.text = yourString.html2String 또는

label.text = yourString.html2String

1
예,하지만 HTML의 텍스트에서만 작동합니다. 나는 또한 이미지와 목록에 대해 걱정했습니다. 이미지와 목록을 표시하는 방법이 하나의 개체입니까 ??
Talha Ahmad Khan

@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
SWIFT 3.1 NSCharacterEncodingDocumentAttribute : String.Encoding.utf8.rawValue
캔 AKSOY

4

스위프트 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


3

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"과 같은 HEX 형식으로 색상을 추가하거나 "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/


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의 텍스트에서만 작동합니다. 나는 또한 이미지와 목록에 대해 걱정했습니다. 이미지와 목록을 표시하는 방법이 하나의 개체입니까 ??
Talha Ahmad Khan

3
사용 NSHTMLTextDocumentType엄청나게 느립니다 [1]. 대신 DDHTML 과 같은 라이브러리를 사용해보십시오 . [1] robpeck.com/2015/04/nshtmltextdocumenttype-is-slow
크리스토퍼 케빈 하웰

2

위의 답변에 대한 Thx는 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 ?? ""
    }
}


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()

0

나는이 맨 위에 조금 보이는 것하지만 ... 알고 이 코드는 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 }
}

-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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.