はじめに
どうも@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
}
}
終わりに
今回はリンクのみタップ可能になる方法のご紹介でした。
かなり簡単にイライラする要因がなくなるため嬉しいですね。
参考にしたサイト