質問

のインスタンスを使用しています UIWebView テキストを処理して正しく色付けする場合、結果は HTML として表示されますが、 UIWebView を使用して表示したい Core Text とともに NSAttributedString.

を作成したり描画したりすることができます。 NSAttributedString しかし、HTML を属性付き文字列に変換してマッピングする方法がわかりません。

Mac OS X ではそれを理解しています NSAttributedString があります initWithHTML: ただし、これは Mac のみの追加であり、iOS では利用できません。

これと同様の質問があることも知っていますが、回答はありませんでした。もう一度試して、これを行う方法を誰かが作成したかどうか、作成している場合は共有できるかどうかを確認してみようと思いました。

役に立ちましたか?

解決

iOS 7 では、UIKit に initWithData:options:documentAttributes:error: を初期化できるメソッド NSAtttributedString HTML を使用する例:

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

スウィフトの場合:

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)

他のヒント

作業中のGithubでオリバーDrobnikによってNSAttributedStringするにhref="https://github.com/Cocoanetics/DTCoreText">オープンソースのほか

HTMLからNSAttributedStringを作成するメインスレッドで実行する必要があります!

更新:それはNSAttributedString HTMLレンダリングがボンネットの下のWebKitに依存し、をメインスレッドの上で実行する必要がありますか、それは時折SIGTRAP

新しいRelicのクラッシュログます:

 ここに画像の説明を入力

以下は、更新のスレッドセーフのスウィフト2文字列の拡張機能です。

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

使用方法:

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

出力:

 ここに画像の説明を入力

NSAttributedString の Swift イニシャライザ拡張機能

私の傾向としては、これを拡張機能として追加することでした NSAttributedString それよりも String. 。静的拡張機能と初期化子として試してみました。私は以下に含めた初期化子を好みます。

スイフト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)
}

スイフト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)
}
}

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

このはStringとしてHTML文字列を返すためにスウィフトで書かれNSAttributedString拡張機能です。

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

を使用するには、

label.attributedText = "<b>Hello</b> \u{2022} babe".htmlAttributedString()
上で、私は意図的にそれが正しくUnicodeをレンダリングすることを示すためにユニコード\ u2022を追加しました。

些細:(!ないUTF8)。そのNSAttributedStringの用途をコードするデフォルトはNSUTF16StringEncodingです。

スウィフト3.0 Xcodeの8バージョン

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
}

スイフト4


  • NSAttributedString コンビニエンス初期化子
  • 追加のガードなし
  • エラーがスローされます

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

}

使用法

UILabel.attributedText = try? NSAttributedString(htmlString: "<strong>Hello</strong> World!")
あなたが今持っている唯一の解決策は、HTMLを解析し、与えられた点/フォントは/ etc属性を持ついくつかのノードを構築し、NSAttributedStringにそれらを一緒に結合することです。それは多くの作業だが、正しく行われていれば、将来的に再利用可能なことができます。

アンドリューののソリューションにいくつかの変更を作り、スウィフト3にコードを更新します:

このコードは、現在selfとその元のフォント、フォントサイズ、テキストの色を継承することができるようにUITextViewを使用する

注:toHexString()はこちら

から拡張したものです
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)
            }
        }
    }
}

使用例:

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

上記の解決策は正しいです。

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

ただし、iOS 8.1、2、または 3 で実行している場合、アプリはクラッシュします。

クラッシュを避けるためにできることは次のとおりです。これをキューで実行します。常にメインスレッド上にあるようにします。

NSHTMLTextDocumentTypeの使用は遅いですし、スタイルを制御することが困難です。私はあなたがAtributikaと呼ばれている私のライブラリを試してみることをお勧め。これは、独自の非常に高速なHTMLパーサを持っています。また、あなたは、任意のタグ名を持っており、彼らのために任意のスタイルを定義することができます。

例:

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

label.attributedText = str

あなたがここでそれを見つけることができます https://github.com/psharanda/Atributikaする

スイフト3:
これを試して:

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

そして使用する場合:

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

参考拡張機能

iOSのグルメクックブックP.80で

このスレッドに触発され、ポッド、そしてエリカSadunのにObjCの例では、私は、HTML、プレーン弦とNSAttributedStringsおよびその逆の間を行き来するString上とNSAttributedStringの拡張を書きました - GitHubのここを、私が役に立ったと評価している。

署名するである(再び、要旨において完全なコード、リンク上):

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 }
フォント

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

その代わりに、あなたはこれが由来したバージョンとのセットを使用することができます 設定後、UILabelのフォントAttributedStringの

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top