iOS
Swift
swift4

iOSでHTMLタグを使ったものを表示する方法

今回の仕様で管理画面から <b> タグつかって特定の文字列をboldにしたいという要望があったのでパースとかしないでそのままHTMLでうまく表示できないのかなと思って調べてみました。

単純にStringで渡ってきた こんにちは、今日は<b>天気</b>がいい。 の天気をboldにしたい場合はSwift 4だと以下のようにすればいけます。

String.swift
extension String {
    var htmlToAttributedString: NSAttributedString? {
        do {
            guard let data = 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で指定したfontは効かないんですよね。
なので以下のようにするとfont-sizeとfont-family指定できるようになります。

String.swift
extension String {
    func htmlToAttributedString(family: String?, size: CGFloat) -> NSAttributedString? {
        do {
            let htmlCSSString = "<style>" +
                "html *" +
                "{" +
                "font-size: \(size)pt !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
        }
    }
}

attributedTextに↑の方法で変換したものをセットしてあげればHTMLタグを使った文章がそのまま表示できます。

FooTableViewCell.swift
func bindViewModel(_ vm: ViewModel) {
    self.bar.attributedText = barText.htmlToAttributedString(family: "Helvetica", size: 10.0)
}

これでWebのようにiOSのアプリでも
こんにちは、今日は<b>天気</b>がいい。 という文字列が渡ってきたら
こんにちは、今日は天気がいい。
と表示されるようになります。

参考
A Swift extension for String and HTML