😸

【iOS】NSMutableAttributedStringでlinkTextAttributesのスタイルを複数適用したい

2023/08/14に公開

iOSのStringは、リンク付きの書式など、HTMLだとできているような文字装飾ができません。
凝った文字装飾をしたいとき、NSMutableAttributedStringを使うかと思います。

今回の要件

今回、リンク付き書式を複数並べるUIがありまして、その中の一行だけ色を変えたい、という要件がありました。

•リンク付きのメッセージ1
•リンク付きのメッセージ2
(以下略)

こんな感じの並びで、一行だけ目立たせたい、というものでした。

サンプルコード

やろうとしてることは、こんな感じです。

private var textView: UITextView = {
    let view = UITextView()
    return view
}()

private var message: String = """
    •リンク付きのメッセージ1
    •リンク付きのメッセージ2
"""

private func addMessages() {
    let attributedString = NSMutableAttributedString(string: message, attributes: [
        // 基本となる書式
    ])

    addLink(attributedString: attributedString, target: "•リンク付きのメッセージ1", link: "https://xxx")
    addLink(attributedString: attributedString, target: "•リンク付きのメッセージ2", link: "https://yyy")
    textView.attributedText = attributedString
    textView.linkTextAttributes = [
        // リンク付き書式
    ]
}

private func addLink(attributedString: NSMutableAttributedString, target: String, link: String) {
    let range = (attributedString.string as NSString).range(of: target)
    if range.location != NSNotFound {
        attributedString.addAttributes([
            // 個別に設定する書式
        ], range: range)
    }
}

最初は色を変えたい行に対してのみ違う書式をあてることで色を変えられるかと思ったのですが、
リンク付き書式はどうしてもlinkTextAttributesが適用されてしまい、同じ文字装飾になってしまいました。

解決法

リンク付き書式を複数スタイル適用したければ、UITextViewを複数使うしかないのかな〜とまで思ったんですが、解決法を見つけました。

https://stackoverflow.com/questions/49880284/two-hyperlinks-in-uitextview-with-different-colors

linkTextAttributesを潰してしまうことで、個別に設定した書式が有効になります。

textView.linkTextAttributes = [:]

おまけ

MacではAlt+8で「•」が出せることをこれやっててはじめて知りました。
「・」(日本語の中黒)だと全角文字なので、Alt+8の方がコンピューターとは相性良さそうです。
(了)

Discussion