You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为NSAttributedString添加target以实现UITextView中的可点击文本

实现UITextView中AttributedString可点击效果的方案

优先推荐使用系统原生支持的link属性方案,适配性更高,实现成本更低。

方案1:系统link属性实现(推荐)

该方案利用UITextView原生支持的链接识别能力,无需自定义手势,适配iOS 7+所有系统版本。

  • 第一步:构造包含可点击片段的富文本,给要点击的字符串添加link属性,值使用自定义scheme的URL方便识别动作
// 拼接原有文本和可点击文本
let fullContent = NSMutableAttributedString(string: "原有内置的段落文本内容 ")
let clickStr = NSAttributedString(
    string: "点击查看更多",
    attributes: [
        .link: URL(string: "customAction://showMore")!
    ]
)
fullContent.append(clickStr)

// 赋值给UITextView
textView.attributedText = fullContent
// 必须配置的两个属性,否则交互无法触发
textView.isEditable = false
textView.isSelectable = true
// 自定义链接的显示样式
textView.linkTextAttributes = [
    .foregroundColor: UIColor.blue,
    .underlineStyle: NSUnderlineStyle.single.rawValue
]
// 设置代理
textView.delegate = self
  • 第二步:实现UITextViewDelegate方法,拦截链接点击执行自定义逻辑
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
    // 匹配我们自定义的动作scheme
    if URL.scheme == "customAction" {
        switch URL.host {
        case "showMore":
            // 此处写你的点击触发逻辑
            print("可点击文本被触发")
        default: break
        }
        // 返回false阻止系统默认打开URL的行为
        return false
    }
    // 其他正常链接返回true交给系统处理
    return true
}

方案2:自定义属性+点击识别(灵活度更高)

如果需要完全自定义点击逻辑、不使用系统链接样式,可以通过自定义富文本属性加点击手势识别实现。

  • 第一步:给可点击文本添加自定义属性标记
let customActionKey = NSAttributedString.Key("CustomClickAction")
let fullContent = NSMutableAttributedString(string: "原有内置的段落文本内容 ")
let clickStr = NSAttributedString(
    string: "点击查看更多",
    attributes: [
        .foregroundColor: UIColor.green,
        customActionKey: "showMore"
    ]
)
fullContent.append(clickStr)
textView.attributedText = fullContent
textView.isEditable = false
textView.isSelectable = true
  • 第二步:给UITextView添加点击手势,识别点击位置的文本属性
// 添加点击手势
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTextViewTap(_:)))
textView.addGestureRecognizer(tapGesture)

@objc func handleTextViewTap(_ gesture: UITapGestureRecognizer) {
    let textView = gesture.view as! UITextView
    let location = gesture.location(in: textView)
    // 获取点击位置对应的字符索引
    guard let charIndex = textView.layoutManager.characterIndex(
        for: location,
        in: textView.textContainer,
        fractionOfDistanceBetweenInsertionPoints: nil
    ) else { return }
    
    // 检查该位置的字符是否有我们自定义的属性
    let customActionKey = NSAttributedString.Key("CustomClickAction")
    if charIndex < textView.attributedText.length {
        let attributes = textView.attributedText.attributes(at: charIndex, effectiveRange: nil)
        if let actionName = attributes[customActionKey] as? String {
            if actionName == "showMore" {
                // 执行点击逻辑
                print("可点击文本被触发")
            }
        }
    }
}

注意事项

  • 两个方案都必须保证isEditable = false、isSelectable = true,缺少任意一个属性都会导致点击无法触发
  • 方案1的系统link样式可以通过linkTextAttributes完全自定义,不需要使用系统默认的蓝色下划线样式
  • 如果不需要UITextView的文本选择功能,可以自定义手势屏蔽选择行为,只保留点击识别能力

内容的提问来源于stack exchange,提问作者aFella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:24:04