2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UITextViewの選択を無効化しリンクのみタップを可能にする

Posted at

はじめに

どうも@kaneko77です
たまーにあるリンク化したテキストを実装する際、
リンク以外もタップできちゃう問題発生する時あると思います。
今回はそちらに焦点を当てて解決策を共有していきたいと思います。

環境

Xcode13
Swift5.5
IOS15

遭遇シーン

以下挙動があると思います。
リンク入れたけど他タップできるやん!!ですね。

それをリンクのタップだけ機能して他はタップできないように実装しました。

コード

それではどういう風に書いてどういう風に呼び出すか書いてきます。
大層に呼び出しとか言ってますが、実際にはUITextViewのカスタムクラスを作成して、
そのカスタムクラスを呼び出す形になっています。

 呼び出し側
let hogeText: CustomTextView = {
    let textView = CustomTextView()
    textView.translatesAutoresizingMaskIntoConstraints = false
    textView.font = .boldSystemFont(ofSize: 20)
    textView.textColor = .black
    textView.textAlignment = .center
    textView.isSelectable = true
    textView.isEditable = false
    textView.isScrollEnabled = false
    let text = "設定アプリを開きたい場合は⑴こちら\n Googleを表示したい方は⑵こちら"
    let attributeds = NSMutableAttributedString(string: text)
    attributeds.addAttribute(
        .link,
        value: UIApplication.openSettingsURLString,
        range: NSString(string: text).range(of: "⑴こちら")
    )
    
    attributeds.addAttribute(
        .link,
        value: "https://www.google.co.jp/",
        range: NSString(string: text).range(of: "⑵こちら")
    )
    textView.attributedText = attributeds
    return textView
}()
 呼び出し元
import UIKit

class CustomTextView: UITextView {

    // MARK: - リンクのみタップ可能にする
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        guard let p = closestPosition(to: point),
              let range = tokenizer.rangeEnclosingPosition(
                p, with: .character,
                inDirection: UITextDirection(rawValue: UITextLayoutDirection.left.rawValue)
              ) else {
                  return false
              }
        let link = attributedText.attribute(
            .link, at: offset(from: beginningOfDocument, to: range.start), effectiveRange: nil
        )
        return link != nil
    }

    // MARK: - テキスト選択時にメニューの表示を禁止する
    override func becomeFirstResponder() -> Bool {
        return false
    }

}

終わりに

今回はリンクのみタップ可能になる方法のご紹介でした。
かなり簡単にイライラする要因がなくなるため嬉しいですね。

参考にしたサイト

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?