在Swift中如何为UILabel添加可点击跳转的链接?
实现UILabel指定文本区域点击跳转的方案
下面提供两种主流实现方式:
方案1:使用UILabel + 点击手势实现
- 第一步:开启UILabel的用户交互,同时设置富文本高亮可点击区域
// Swift示例代码 let label = UILabel() label.isUserInteractionEnabled = true // 必须开启,默认关闭 let fullText = "click here" let attributedStr = NSMutableAttributedString(string: fullText) // 高亮here部分,可自定义颜色、下划线等样式 let clickRange = (fullText as NSString).range(of: "here") attributedStr.addAttribute(.foregroundColor, value: UIColor.blue, range: clickRange) attributedStr.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: clickRange) label.attributedText = attributedStr
- 第二步:给UILabel添加点击手势,判断点击位置是否落在指定文本范围
// 添加点击手势 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(labelTapped(_:))) label.addGestureRecognizer(tapGesture) // 点击事件处理 @objc func labelTapped(_ gesture: UITapGestureRecognizer) { guard let label = gesture.view as? UILabel, let attributedText = label.attributedText else { return } let fullText = attributedText.string let targetRange = (fullText as NSString).range(of: "here") // 初始化TextKit组件计算点击位置对应的文字范围 let layoutManager = NSLayoutManager() let textContainer = NSTextContainer(size: label.bounds.size) let textStorage = NSTextStorage(attributedString: attributedText) layoutManager.addTextContainer(textContainer) textStorage.addLayoutManager(layoutManager) textContainer.lineFragmentPadding = 0 textContainer.lineBreakMode = label.lineBreakMode textContainer.maximumNumberOfLines = label.numberOfLines let tapLocation = gesture.location(in: label) let characterIndex = layoutManager.characterIndex(for: tapLocation, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil) // 判断点击位置是否在目标范围内 if NSLocationInRange(characterIndex, targetRange) { // 执行跳转逻辑 guard let url = URL(string: "https://www.google.com") else { return } UIApplication.shared.open(url) } }
方案2:使用UITextView简化实现(推荐)
UITextView原生支持链接点击检测,实现成本更低:
let textView = UITextView() textView.isEditable = false textView.isScrollEnabled = false textView.textContainerInset = .zero textView.textContainer.lineFragmentPadding = 0 textView.delegate = self let fullText = "click here" let attributedStr = NSMutableAttributedString(string: fullText) let clickRange = (fullText as NSString).range(of: "here") // 直接给指定范围加链接属性 attributedStr.addAttribute(.link, value: "https://www.google.com", range: clickRange) // 可自定义链接样式 textView.linkTextAttributes = [.foregroundColor: UIColor.blue, .underlineStyle: NSUnderlineStyle.single.rawValue] textView.attributedText = attributedStr
实现UITextViewDelegate方法处理链接点击:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { UIApplication.shared.open(URL) return false }
注意事项
- 计算文本范围时要保证UILabel/UITextView的尺寸已经确定,否则会出现范围计算偏差,建议在视图布局完成后再做相关配置
- 多行文本场景下更推荐使用UITextView方案,范围计算更稳定
内容的提问来源于stack exchange,提问作者Trev347
相关产品推荐
相关产品推荐

