iOS - Swift 如何在 UILabel 中点击链接

iOS - Swift how to make links clicked in UILabel

这是我在 UILabel 中显示链接的代码

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textFiled: UITextField!

    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let attrStr = try! NSAttributedString(
            data: "This is a link <a href='http://www.google.com'>google</a>".dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!,
            options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
            documentAttributes: nil)
        label.attributedText = attrStr
    }

}

从图片中可以看出,它正确显示了link,我只是想要它,但是link不能点击跳转到网页视图或其他。实际上,我需要自定义link点击事件,我真的不知道:

  1. 如何获取 link 的 URL。
  2. 如果有多个link,我需要做什么。

感谢您首先检查此问题。

简短的回答是 UILabel 不支持打开 URL。它可以检测到 link 存在,但它不会做任何事情。

您可以找到解决问题的替代方法,您可以阅读相关内容 here

正如卢克所说 UI标签不支持 URL。但是您可以创建一个看起来像标签的按钮。摆脱背景(所以它看起来像文本)并实现按钮的功能以打开 webview。您可以使用属性字符串来编辑按钮中文本的样式。

当您将按钮添加到您的 UI 时,您将要考虑使用自定义 class 而不是默认的 uibutton class。

您将需要:

  1. 初始化

     - (instancetype)initWithFrame:(CGRect)frame {
       self = [super initWithFrame:frame];
         if (self)
         {
             //call the method to configure the button
             [self configure];
         }
       return self;
     }
    
  2. 如果您使用属性字符串,请执行 setTitle 或 setAttributedTitle

     - (void) setTitle:(NSString *)title forState:(UIControlState)state
     {
            [super setTitle:title forState:state]
     }      
    

      - (void)setAttributedTitle:(NSAttributedString *)title forState:   (UIControlState)state{
            [super setAttributedTitle:title forState:state];
         }

3。配置按钮

         -(void) configure{
             //configure the buttons label here 
             //you will want to set no background colour
          }

4。将按钮添加到 viewcontroller 并将 class 更改为您创建的自定义 class。

强烈建议使用 UITextView 对象而不是 UILabel,但是您可以使用 KILabel 项目作为 UILabel 的替代品。 参见 https://github.com/Krelborn/KILabel/blob/master/README.md

这是满足您需求的基本方法,我习惯于创建可点击的标签

private let linkLabel: UILabel = {
    let label = UILabel()
    label.text = "Link"
    return label
}()

  func setup() {
        linkLabel.isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: #selector(openLink))
        linkLabel.addGestureRecognizer(tap)
}

    if let openLink = URL(string: "http://www.apple.com") {
    if UIApplication.shared.canOpenURL(url) {
        UIApplication.shared.open(url, options: [:])
    }
}

对于链接,通常正确的答案是使用UITextView

但我知道额外的两个子视图对于简单的用例来说可能有点重。 UILabel 子类很好,但是你不能使用你自己的子类。其他答案都依赖于重新创建您自己的文本堆栈,希望 模仿 UILabel 使用的文本堆栈,尽管当文本开始缩小时很快就会失败。

正因如此,我创建了 LinkGestureRecognizer (https://github.com/stuartjmoore/UILabel-LinkGestureRecognizer) 来满足您的所有 UILabel 需求。

就这么简单:

let label = UILabel()
label.attributedText = // An attributed string with inline link ranges

let linkGestureRecognizer = LinkGestureRecognizer(target: self, action: #selector(handleLinkTap))
label.addGestureRecognizer(linkGestureRecognizer)

@objc func handleLinkTap(_ gestureRecognizer: LinkGestureRecognizer) {
    // handle gestureRecognizer.url in gestureRecognizer.range (UTF-16)
}