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

添加UITapGestureRecognizer后TTTAttributedLabel链接无法点击求助

解决TTTAttributedLabel同时支持@提及和URL点击的方案

这个问题我之前也碰到过,核心原因是你自己添加的UITapGestureRecognizer和TTTAttributedLabel内部的手势逻辑冲突了——TTT本身已经自带了处理链接点击的手势,额外添加的手势会干扰它的正常工作,哪怕设置了shouldRecognizeSimultaneouslyWith返回true也没用。给你一套更兼容的方案,完全基于TTT的原生机制来实现,既能保留URL点击,又能搞定@提及的识别:

步骤1:移除自定义手势,启用TTT的URL识别

先把你自己加的UITapGestureRecognizer代码删掉,然后开启TTT对URL的原生识别:

commentLabel.isUserInteractionEnabled = true
// 启用URL识别
commentLabel.enabledTextCheckingTypes = NSTextCheckingResult.CheckingType.link.rawValue
// 设置TTT的代理,用于处理点击事件
commentLabel.delegate = self

步骤2:给@提及内容添加自定义链接

我们可以把@提及的文本标记为TTT能识别的自定义链接,用自定义URL Scheme来区分普通URL和@提及。写一个文本处理方法:

func processCommentText(_ text: String) -> NSAttributedString {
    let attributedString = NSMutableAttributedString(string: text)
    
    // 正则匹配所有@开头的提及内容
    let mentionPattern = "@\\w+"
    do {
        let regex = try NSRegularExpression(pattern: mentionPattern, options: [])
        let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))
        
        for match in matches {
            let mentionRange = match.range
            // 提取用户名(去掉开头的@)
            let username = (text as NSString).substring(with: NSRange(location: mentionRange.location + 1, length: mentionRange.length - 1))
            // 创建自定义URL,用user://作为Scheme
            let userURL = URL(string: "user://\(username)")!
            
            // 给@提及内容添加TTT的链接属性
            attributedString.addAttribute(kTTTAttributedLabelLinkAttributeName, value: userURL, range: mentionRange)
            // 可选:设置@提及的文本样式(比如蓝色)
            attributedString.addAttribute(.foregroundColor, value: UIColor.systemBlue, range: mentionRange)
        }
    } catch {
        print("匹配@提及出错:\(error)")
    }
    
    return attributedString
}

然后把处理后的富文本赋值给标签:

commentLabel.attributedText = processCommentText("你的评论内容,比如@Lucas 你好,这是链接https://example.com")

步骤3:实现TTT代理方法区分处理点击

通过TTT的代理方法,我们可以判断点击的是普通URL还是@提及,分别处理:

extension YourViewController: TTTAttributedLabelDelegate {
    func attributedLabel(_ label: TTTAttributedLabel!, didSelectLinkWith url: URL!) {
        if url.scheme == "user" {
            // 处理@提及点击,url.host就是提取出的用户名
            if let username = url.host {
                print("点击了@\(username)")
                // 这里添加你的@提及逻辑,比如跳转到用户主页
            }
        } else {
            // 处理普通URL点击,比如打开浏览器
            if UIApplication.shared.canOpenURL(url) {
                UIApplication.shared.open(url)
            }
        }
    }
}

为什么这个方案可行?

TTTAttributedLabel的核心逻辑就是通过识别文本中的链接属性(kTTTAttributedLabelLinkAttributeName)来处理点击,不管是原生的URL还是我们自定义的@提及链接,都会被它统一处理,完全不会出现手势冲突的问题,而且能完美保留两种点击功能。

内容的提问来源于stack exchange,提问作者Lucas P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:52:32