iOS/Swift:将 UITapGestureRecognizer 添加到 NSMutableAttributedString

iOS/Swift: Add UITapGestureRecognizer to NSMutableAttributedString

我想知道是否可以将 UITapGestureRecognizer 添加到 NSMutableAttributedString

我想要做的是在字符限制 UITextView 的最后一个单词之后有一个 "more..." 对象。为了让对象在最后一个词之后立即出现,似乎最好让 UITextView 接受属性文本(而不是纯文本),然后附加一个 NSMutableAttributedString 类型的蓝色 "more..." .

我看到有人通过将点击手势添加到封闭的 UITextView 来实现此目的的示例,但这还不够,因为我希望仅当他们点击 "more..." 时才会发生操作在文本视图中属性字符串的末尾。我想看看有没有办法直接在属性字符串中添加点击手势。

首先,无法向 NSMutableAttributedString 添加手势识别器,因为属性字符串对其在屏幕中的位置或用户触摸一无所知。

获取在 UITextView 中绘制的属性字符串的过程主要由三个 类 控制:NSTextStorageNSTextContainerNSLayoutManager。如果您想更多地了解它们的工作原理,请查看 this awesome tutorial

阅读该教程后,您应该知道无需向属性字符串添加点击手势识别器即可获得所需内容。如果您不需要 UITextView 可编辑,解决方案是将蓝色 More... 视为 link 并附加自定义操作以在用户触摸它时做出响应。这是 this link 中 objective-c 代码的 Swift 翻译,以说明如何实现:

class ViewController: UIViewController, UITextViewDelegate {
    @IBOutlet weak var textView: UITextView!

   override func viewDidLoad() {
      super.viewDidLoad()
      let str = NSMutableAttributedString(
          string: "This is a sample text that is very long but you can see it completely because More..."
      )
      str.addAttribute(
         NSLinkAttributeName,
         value: "more://",
         range: (str.string as NSString).range(of: "More...")
      )
  
      textView.attributedText = str
      textView.delegate = self
      textView.isSelectable = true
      textView.isEditable = false
   }

   func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
      if URL.scheme == "more" {
         print("TODO: Handle more action here")
         return false
      }
      else {
         return true
      }
   }
}