Ios 带有链接和UIAPTgestureRecognitor的UILabel

Ios 带有链接和UIAPTgestureRecognitor的UILabel,ios,swift,swift3,uilabel,uigesturerecognizer,Ios,Swift,Swift3,Uilabel,Uigesturerecognizer,我有一个带有文本和链接的ui标签。链接只是文本的一部分,而不是全部,但是,它在文本中的位置可能会更改 我已经使用了TTTAttributedLabel来检测链接,现在我想在文本的其余部分添加一个手势识别器,它不是链接。因为,链接位置可能会改变,我不确定这将如何实现 在没有外部库的情况下可以这样做吗?将其放入viewDidLoad: self.textLabel.text = "Try to open https://www.google.com" let text = self.textLabe

我有一个带有文本和链接的
ui标签
。链接只是文本的一部分,而不是全部,但是,它在文本中的位置可能会更改

我已经使用了
TTTAttributedLabel
来检测链接,现在我想在文本的其余部分添加一个手势识别器,它不是链接。因为,链接位置可能会改变,我不确定这将如何实现


在没有外部库的情况下可以这样做吗?

将其放入
viewDidLoad

self.textLabel.text = "Try to open https://www.google.com"
let text = self.textLabel.text
let sep = text?.components(separatedBy: " ")
for i in sep! {
    if isURL(string: i) {
        canopen.append(i)
    }
}
更易于处理标签攻丝的扩展:

extension UITapGestureRecognizer {

    func didTapText(in label: UILabel, range targetRange: NSRange) -> Bool {

        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: CGSize.zero)
        let textStorage = NSTextStorage(string: label.text!)
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        // Configuration must be the same as the label!
        textContainer.lineFragmentPadding = 0.0
        textContainer.lineBreakMode = label.lineBreakMode
        textContainer.maximumNumberOfLines = label.numberOfLines
        let labelSize = label.bounds.size
        textContainer.size = labelSize

        // Find the tapped character location and compare it to the specified range
        let locationOfTouchInLabel = self.location(in: label)
        let textBoundingBox = layoutManager.usedRect(for: textContainer)
        let textContainerOffset = CGPoint(x: (labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)
        let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y)
        let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        return NSLocationInRange(indexOfCharacter, targetRange)
    }

}
然后放置一个helper函数以确定它是否为url:

func isURL(string: String?) -> Bool {
    guard let urlString = string else {return false}
    guard let url = URL(string: urlString) else {return false}
    if !UIApplication.shared.canOpenURL(url) {return false}

    let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
    let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx])
    return predicate.evaluate(with: string)
}
这就是要在手势的
@IBAction
中输入的内容,其中
IBAction
的参数是
uitagesturerecognizer
,而不是
Any?

let text = self.textLabel.text

for i in canopen {
    if sender.didTapText(in: textLabel, range: (text! as NSString).range(of: i)) {
        print("Tapped on a link, so do nothing")
        return
    }
}

print("Did not tap on a link, so do something")
<#code#>
let text=self.textlab.text
因为我在卡诺彭{
if sender.didTapText(in:textlab,range:(text!as NSString).range(of:i)){
打印(“点击链接,所以什么也不做”)
返回
}
}
打印(“没有点击链接,所以做点什么”)

参考资料:

将其放入
viewDidLoad

self.textLabel.text = "Try to open https://www.google.com"
let text = self.textLabel.text
let sep = text?.components(separatedBy: " ")
for i in sep! {
    if isURL(string: i) {
        canopen.append(i)
    }
}
更易于处理标签攻丝的扩展:

extension UITapGestureRecognizer {

    func didTapText(in label: UILabel, range targetRange: NSRange) -> Bool {

        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: CGSize.zero)
        let textStorage = NSTextStorage(string: label.text!)
        layoutManager.addTextContainer(textContainer)
        textStorage.addLayoutManager(layoutManager)

        // Configuration must be the same as the label!
        textContainer.lineFragmentPadding = 0.0
        textContainer.lineBreakMode = label.lineBreakMode
        textContainer.maximumNumberOfLines = label.numberOfLines
        let labelSize = label.bounds.size
        textContainer.size = labelSize

        // Find the tapped character location and compare it to the specified range
        let locationOfTouchInLabel = self.location(in: label)
        let textBoundingBox = layoutManager.usedRect(for: textContainer)
        let textContainerOffset = CGPoint(x: (labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)
        let locationOfTouchInTextContainer = CGPoint(x: locationOfTouchInLabel.x - textContainerOffset.x, y: locationOfTouchInLabel.y - textContainerOffset.y)
        let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        return NSLocationInRange(indexOfCharacter, targetRange)
    }

}
然后放置一个helper函数以确定它是否为url:

func isURL(string: String?) -> Bool {
    guard let urlString = string else {return false}
    guard let url = URL(string: urlString) else {return false}
    if !UIApplication.shared.canOpenURL(url) {return false}

    let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
    let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx])
    return predicate.evaluate(with: string)
}
这就是要在手势的
@IBAction
中输入的内容,其中
IBAction
的参数是
uitagesturerecognizer
,而不是
Any?

let text = self.textLabel.text

for i in canopen {
    if sender.didTapText(in: textLabel, range: (text! as NSString).range(of: i)) {
        print("Tapped on a link, so do nothing")
        return
    }
}

print("Did not tap on a link, so do something")
<#code#>
let text=self.textlab.text
因为我在卡诺彭{
if sender.didTapText(in:textlab,range:(text!as NSString).range(of:i)){
打印(“点击链接,所以什么也不做”)
返回
}
}
打印(“没有点击链接,所以做点什么”)

参考:

如果UIlabel的使用不是强制性的。您可以使用UIExtView来检测链接,也可以单击该链接。

如果UIlabel的使用不是强制性的。您可以使用UITextview来检测链接,也可以单击该链接。

您是否尝试过使用任何pod,如或?谢谢@Macabeus,我正在尝试找到一个本机解决方案。您说:“在非链接的文本上添加可识别的手势”。你确定吗?这似乎很奇怪。只是澄清一下。是的,我就是这个意思。感谢您澄清@paper1111@Forge您的问题得到解决了吗?您是否尝试过使用任何pod,如或?谢谢@Macabeus,我实际上正在尝试找到解决此问题的本机解决方案。您说:“在文本上添加可识别的手势,而不是链接”。你确定吗?这似乎很奇怪。只是澄清一下。是的,我就是这个意思。谢谢你澄清@paper1111@Forge你的问题解决了吗