Swift2.xでUITextView内のテキストをHTMLとして表示する


APIから取得した情報を表示する際にはリンク付テキストやCSS付きのテキストで表示したい場合も多いはず

iOS開発の中でもWebAPIとの連携する場合等、HTMLタグ付きの情報を取得してUITextViewに表示させたい場合があったので試してみたのですが、少しハマってしまいましたので、その方法を備忘録も兼ねて記しておこうと思います。

■ 私の使用環境:

  • OS:Yosemite 10.10.5 ※まだEl Capitanにはしていません><
  • XCode:XCode 7.1.1
  • Swift:Swift2.1

ポイントとなるのはNSAttributedString

上記のNSAttributedStringを使用することによって、UILabelやUITextViewに対して文字の一部やフォントなどを変更することができます。
今回は下記のような見た目のものをUITextFieldを使って再現するコードになります。

そして実際のコード例は下記になります。

●●●●.swift
//事前の準備としてtargetTextViewというUITextViewのインスタンスを作成。

//配置したUITextViewのインスタンスに対してリンクを有効にする
self.targetTextView.dataDetectorTypes = .Link

//HTMLタグが混在している文字列に対してHTMLで表示させるようにする処理
//※ "(ダブルクオーテーション)の前に、\(バックスラッシュ)をつけること
do {

    //対象のテキスト
    let htmlText: String =
        "テキストカラーは<font color=\"blue\">青色</font>です。<br>" +
        "テキストカラーは<font color=\"red\">赤色</font>です。<br>" +
        "ヤフージャパンへのリンクは<a href=\"http://www.yahoo.co.jp/\"><strong>こちら</strong></a><br>" +
        "CSSスタイルは<strong style=\"color:#663399;\">こんな風に</strong>適用されます。"

    //テキストをUTF-8エンコード
    let encodedData = htmlText.dataUsingEncoding(NSUTF8StringEncoding)!

    //表示データのオプションの設定
    let attributedOptions : [String : AnyObject] = [
        NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, //表示データのドキュメントタイプ
        NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding, //表示データの文字エンコード
    ]

    //文字列の変換処理の実装(try 〜 catch構文を使っています。)
    let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)

    //HTMLとしてUITextViewに表示する
    self.targetTextView.attributedText = attributedString

//ここは例外処理
} catch {
    fatalError("Unhandled error: \(error)")
}

※もちろん上記はリンクを押すと遷移します&直書きのスタイルも反映されています。

Swiftも今は少し落ち着いた感はあるのですが、バージョンアップを重ねていくうちに、同じ処理でも微妙に記法が違っていたりして「思わず時間を食ってしまった…」的なことになってしまいました。この部分に関しては旧のバージョンでは動いていたのにというものでも、Swift2.x系でどのように変わったかの振る舞いは今後もう少し深掘る必要がありそうですね。

参考にしたもの一覧

※引用:NSAttributedStringによる文字装飾
(こちらはObjective-Cでの記事になりますが「こんなことができるのかー」的な参考になりました。)

※引用:既存コードのSwift2.0とiOS9対応の暫定措置

※引用:Apple公式のドキュメント(NSAttributedStringに関して)

※引用:【iOS】UITextViewの任意の文字列にリンクを埋め込む
(実際に実装を行った際のサンプルで非常に勉強になりました!)

※引用:Swift: Using Attributed Strings in Swift