UITextView
Swift
swift4

SwiftでUITextViewにリンクを挿入して、「プライバシーポリシーはこちら」を作る

はじめに

「プライバシーポリシー、利用規約に同意する」
みたいな会員登録画面などでよく見るリンク付きのUITextViewの設定方法についてです。
単純にURLを設定してそこに遷移する方法と、どのリンクがタップされたのか判定した上で遷移を行う方法をまとめてみました。

URLのリンクに遷移する

単純に設定したURLに遷移させる方法です。これでリンクになっている「こちら」をタップするとヤフーのトップページに遷移します。

スクリーンショット 2018-06-13 23.01.59.png

let textView: UITextView = UITextView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
textView.center = view.center
textView.backgroundColor = .clear
textView.font = UIFont.systemFont(ofSize: 17.0) // フォントの設定をする.
textView.textColor = .white // フォントの色の設定をする.
textView.textAlignment = .center
textView.dataDetectorTypes = .all // リンク、日付などを自動的に検出してリンクに変換する.
textView.isEditable = false // テキストを編集不可にする.

let style = NSMutableParagraphStyle()
style.alignment = .center
let attributedString = NSMutableAttributedString(string: "プライパシーポリシーはこちら")

attributedString.addAttributes([.foregroundColor: UIColor.white, .paragraphStyle: style, .font: UIFont.systemFont(ofSize: 17.0)], range: NSMakeRange(0, attributedString.length))

let range = attributedString.mutableString.range(of: "こちら")
attributedString.setAttributes([.underlineStyle : NSUnderlineStyle.styleSingle.rawValue, .link: URL(string: "https://www.yahoo.co.jp/")!, .foregroundColor: UIColor.white, .paragraphStyle: style,], range: range)

textView.attributedText = attributedString

どのリンクがタップされたのか判定する

単純にURLに遷移するだけなら上の方法でも良いですが、タップ時に何らかの処理をしたい場合やアプリ内の画面に遷移する場合は、UITextViewのデリゲートメソッド内でどのリンクがタップされたのか判別してハンドリングする必要があります。

extension ViewController: UITextViewDelegate {
    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        let urlString = URL.absoluteString
        if urlString.contains("here") {
            print("こちらがタップされました")
            // 何かしらの処理
            return false
        }
        return true
     }
}

拡張関数を作ってみた

私は以下のような拡張関数を定義して使ってます。
個人的にはこの程度の設定があれば十分なので、重宝してます。

extension UITextView {

    func drawUnderLineWithLink(text: String,
                               linedText: [String: URL],
                               color: UIColor = .white,
                               lineStyle: NSUnderlineStyle = .styleSingle,
                               alignment: NSTextAlignment = .center,
                               font: UIFont = UIFont.systemFont(ofSize: 17.0)) {

        let style = NSMutableParagraphStyle()
        style.alignment = alignment

        let attributedString = NSMutableAttributedString(string: text)

        attributedString.addAttributes([.foregroundColor: color,
                                        .paragraphStyle: style,
                                        .font: font],
                                        range: NSMakeRange(0, attributedString.length))

        linedText.forEach { (txt, url) in
            let range = attributedString.mutableString.range(of: txt)
            attributedString.setAttributes([.underlineStyle : lineStyle.rawValue,
                                            .link: url,
                                            .font: font], range: range)
        }
        self.attributedText = attributedString
    }

}

利用方法

        let linedText: [String: URL] = ["続行": URL(string: "https://www.yahoo.co.jp/")!,
                                       "アカウント作成": URL(string: "https://www.yahoo.co.jp/")!,
                                       "もっと": URL(string: "https://www.yahoo.co.jp/")!,
        ]
        textView.drawUnderLineWithLink(text: "続行, アカウント作成, もっとをタップしてください", linedText: linedText)

参考

https://qiita.com/shtnkgm/items/0009ef445a96126d7b16
https://qiita.com/shtnkgm/items/3c8b6b794219fbf087ba