In general detection of a tap in a specific range inside UILabel (or tap of a specific word) could be easily solved using the following extension:
extension UITapGestureRecognizer {
func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
let storage = NSTextStorage(attributedString: label.attributedText!)
let layoutManager = NSLayoutManager()
storage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: label.frame.size)
layoutManager.addTextContainer(textContainer)
textContainer.lineFragmentPadding = 0.0
var glyphRange = NSRange()
layoutManager.characterRange(forGlyphRange: targetRange, actualGlyphRange: &glyphRange)
let glyphRect = layoutManager.boundingRect(forGlyphRange: glyphRange, in: textContainer)
let touchPoint = self.location(ofTouch: 0, in: label)
return glyphRect.contains(touchPoint)
}
}
But, this doesn't work in case if attributed text contains emojis. For example:
Lorem ipsum dolor TAP_HERE lorem ipsum
works fine, but:
Lorem ipsum dolor TAP_HERE lorem ipsum
is not working.
Any ideas?