1

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?

daxh
  • 571
  • 7
  • 14
  • How is called `didTapAttributedTextInLabel(label:inRange:)`? I'm wondering about the range parameter. – Larme Aug 25 '18 at 16:34
  • Range parameter is 100% calculated properly, the only problem is emoji. – daxh Aug 26 '18 at 18:39
  • It's just that aSwiftString.count != aNSString.length (especially for emojis which may be count as 1 or 2), so I'm wondering if the issue isn't there. – Larme Aug 26 '18 at 18:40
  • @daxh were you able to solve this issue? I'm getting the same issue with emojis – Rahim Khalid Jun 03 '21 at 07:37
  • @RahimKhalid to be honest it was so long time ago, that I did not remember anything, sorry – daxh Jun 04 '21 at 11:57

0 Answers0