Frage

Ich bin eine Instanz von UIWebView mit etwas Text zu verarbeiten und es richtig Farbe, es gibt das Ergebnis als HTML, sondern als in den UIWebView Anzeige Ich mag es angezeigt mit einem Core Text mit NSAttributedString.

Ich kann den NSAttributedString erstellen und zu zeichnen, aber ich bin nicht sicher, wie ich umwandeln kann und ordnen Sie den HTML-Code in den zurück String.

Ich verstehe, dass unter Mac OS X NSAttributedString eine initWithHTML: Methode hat aber dies war ein Mac nur hinaus und ist für iOS nicht verfügbar ist.

Ich weiß auch, dass es eine ähnliche Frage dazu ist, aber es hatte keine Antworten, ich obwohl ich wieder versuchen würde, und sehen, ob jemand eine Möglichkeit, dies zu tun, geschaffen hat und wenn ja, ob sie es teilen konnten.

War es hilfreich?

Lösung

In iOS 7, UIKit hinzugefügt, um ein initWithData:options:documentAttributes:error: Methode, die eine NSAtttributedString mit HTML initialisieren kann, zum Beispiel:

[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] 
                                 options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                           NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} 
                      documentAttributes:nil error:nil];

In Swift:

let htmlData = NSString(string: details).data(using: String.Encoding.unicode.rawValue)
let options = [NSAttributedString.DocumentReadingOptionKey.documentType:
        NSAttributedString.DocumentType.html]
let attributedString = try? NSMutableAttributedString(data: htmlData ?? Data(),
                                                          options: options,
                                                          documentAttributes: nil)

Andere Tipps

Es ist ein work-in-progress Open-Source neben NSAttributedString von Oliver Drobnik bei Github. Es verwendet NSScanner für HTML-Analyse.

Erstellen von HTML ein NSAttributedString muss auf dem Haupt-Thread ausgeführt werden!

Update: Es stellt sich heraus, dass NSAttributedString HTML-Rendering auf WebKit unter der Haube ab, und muss auf dem Haupt-Thread ausgeführt wird oder es wird gelegentlich die App mit einem SIGTRAP Absturz .

New Relic Crash-Protokoll:

 image description hier

eingeben

Im Folgenden finden Sie eine aktualisierte thread-safe Swift 2 String-Erweiterung:

extension String {
    func attributedStringFromHTML(completionBlock:NSAttributedString? ->()) {
        guard let data = dataUsingEncoding(NSUTF8StringEncoding) else {
            print("Unable to decode data from html string: \(self)")
            return completionBlock(nil)
        }

        let options = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                   NSCharacterEncodingDocumentAttribute: NSNumber(unsignedInteger:NSUTF8StringEncoding)]

        dispatch_async(dispatch_get_main_queue()) {
            if let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) {
                completionBlock(attributedString)
            } else {
                print("Unable to create attributed string from html string: \(self)")
                completionBlock(nil)
            }
        }
    }
}

Verbrauch:

let html = "<center>Here is some <b>HTML</b></center>"
html.attributedStringFromHTML { attString in
    self.bodyLabel.attributedText = attString
}

Ausgabe:

 image description hier

eingeben

Swift initializer Erweiterung auf NSAttributedString

war meine Neigung dies als eine Erweiterung hinzuzufügen eher zu NSAttributedString als String. Ich habe versucht, es als eine statische Dehnung und Initialisierer. Ich ziehe den initializer das ist, was ich unten aufgeführt haben.

Swift 4

internal convenience init?(html: String) {
    guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
        return nil
    }

    guard let attributedString = try?  NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) else {
        return nil
    }

    self.init(attributedString: attributedString)
}

Swift 3

extension NSAttributedString {

internal convenience init?(html: String) {
    guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
        return nil
    }

    guard let attributedString = try? NSMutableAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) else {
        return nil
    }

    self.init(attributedString: attributedString)
}
}

Beispiel:

let html = "<b>Hello World!</b>"
let attributedString = NSAttributedString(html: html)

Dies ist eine String Erweiterung in Swift geschrieben, um eine HTML-Zeichenfolge als NSAttributedString zurückzukehren.

extension String {
    func htmlAttributedString() -> NSAttributedString? {
        guard let data = self.dataUsingEncoding(NSUTF16StringEncoding, allowLossyConversion: false) else { return nil }
        guard let html = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil }
        return html
    }
}

verwenden,

label.attributedText = "<b>Hello</b> \u{2022} babe".htmlAttributedString()

In der oben habe ich absichtlich eine Unicode \ u2022 zu zeigen, fügte hinzu, dass es Unicode macht richtig.

A trivial. Die Standard-Codierung, die NSAttributedString Anwendungen ist NSUTF16StringEncoding (! Nicht UTF8)

Swift 3.0 Xcode 8 Version

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: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil }
    return html
}

Swift 4


  • NSAttributedString Bequemlichkeit initializer
  • Ohne zusätzliche Wachen
  • wirft Fehler

extension NSAttributedString {

    convenience init(htmlString html: String) throws {
        try self.init(data: Data(html.utf8), options: [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ], documentAttributes: nil)
    }

}

Verwendung

UILabel.attributedText = try? NSAttributedString(htmlString: "<strong>Hello</strong> World!")

Die einzige Lösung, die Sie jetzt haben, ist die HTML zu analysieren, einige Knoten mit bestimmten Punkt aufbauen / font / etc Attribute, so dass sie dann zusammen verbinden sich zu einem NSAttributedString. Es ist eine Menge Arbeit, aber wenn es richtig gemacht, kann in Zukunft wiederverwendbar sein.

Made einige Änderungen auf Andrew 's Lösung und aktualisieren Sie den Code Swift 3:

Dieser Code jetzt UITextView als self und in der Lage verwenden, seine ursprüngliche Schriftart, Schriftgröße und Textfarbe erben

Hinweis: toHexString() ist Erweiterung von hier

extension UITextView {
    func setAttributedStringFromHTML(_ htmlCode: String, completionBlock: @escaping (NSAttributedString?) ->()) {
        let inputText = "\(htmlCode)<style>body { font-family: '\((self.font?.fontName)!)'; font-size:\((self.font?.pointSize)!)px; color: \((self.textColor)!.toHexString()); }</style>"

        guard let data = inputText.data(using: String.Encoding.utf16) else {
            print("Unable to decode data from html string: \(self)")
            return completionBlock(nil)
        }

        DispatchQueue.main.async {
            if let attributedString = try? NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) {
                self.attributedText = attributedString
                completionBlock(attributedString)
            } else {
                print("Unable to create attributed string from html string: \(self)")
                completionBlock(nil)
            }
        }
    }
}

Beispiel Nutzung:

mainTextView.setAttributedStringFromHTML("<i>Hello world!</i>") { _ in }

Die obige Lösung ist richtig.

[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] 
                                 options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                           NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} 
                      documentAttributes:nil error:nil];

Aber die App wioll abstürzen, wenn Sie es auf ios laufen 8.1,2 oder 3.

den Absturz zu vermeiden, was Sie tun können, ist: diese in einer Warteschlange laufen. So dass es immer auf Hauptthread sein.

von NSHTMLTextDocumentType Verwendung ist langsam und es ist schwer zu kontrollieren Stile. Ich schlage vor, Sie meine Bibliothek, um zu versuchen, die Atributika genannt wird. Es hat seinen eigenen sehr schnell HTML-Parser. Auch können Sie alle Tag-Namen haben und definieren jeden Stil für sie.

Beispiel:

let str = "<strong>Hello</strong> World!".style(tags:
    Style("strong").font(.boldSystemFont(ofSize: 15))).attributedString

label.attributedText = str

Sie können es hier finden https://github.com/psharanda/Atributika

Swift 3 :
Versuchen Sie, diese :

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: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
            documentAttributes: nil) else { return nil }
        return html
    }
}  

Und für die Verwendung:

let str = "<h1>Hello bro</h1><h2>Come On</h2><h3>Go sis</h3><ul><li>ME 1</li><li>ME 2</li></ul> <p>It is me bro , remember please</p>"

self.contentLabel.attributedText = str.htmlAttributedString()

Hilfreiche Erweiterungen

durch diesen Thread inspiriert, eine Hülse, und Erica Sadun des ObjC Beispiel in iOS Gourmet-Kochbuch S.80, schrieb ich eine Erweiterung auf String und auf NSAttributedString hin und her zwischen HTML Plain-Strings und NSAttributedStrings und umgekehrt zu gehen - hier , die ich nützlich gefunden haben.

Die Signaturen sind (wieder vollständige Code in einem Gist, Link oben):

extension NSAttributedString {
    func encodedString(ext: DocEXT) -> String?
    static func fromEncodedString(_ eString: String, ext: DocEXT) -> NSAttributedString? 
    static func fromHTML(_ html: String) -> NSAttributedString? // same as above, where ext = .html
}

extension String {
    func attributedString(ext: DocEXT) -> NSAttributedString?
}

enum DocEXT: String { case rtfd, rtf, htm, html, txt }

mit Schrift

extension NSAttributedString
{
internal convenience init?(html: String, font: UIFont? = nil) {
    guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
        return nil
    }
    assert(Thread.isMainThread)
    guard let attributedString = try?  NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) else {
        return nil
    }
    let mutable = NSMutableAttributedString(attributedString: attributedString)
    if let font = font {
        mutable.addAttribute(.font, value: font, range: NSRange(location: 0, length: mutable.length))
    }
    self.init(attributedString: mutable)
}
}

Alternativ können Sie die Möglichkeiten nutzen dies aus und Satz abgeleitet wurde Schriftart auf UILabel nach der Einstellung attributedString

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top