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你的问题解决了吗