添加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.
相关产品推荐
相关产品推荐

