Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extension for UITapGesture that contains a function to detect range of particular text in UILabel's text.
extension UITapGestureRecognizer {
func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: CGSize.zero)
let textStorage = NSTextStorage(attributedString: label.attributedText!)
// Configure layoutManager and textStorage
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
// Configure textContainer
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)
indexOfCharacter = indexOfCharacter + 4
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
@TendiF

This comment has been minimized.

Copy link

TendiF commented Nov 8, 2019

thanks this helping me

@Tovkal

This comment has been minimized.

Copy link

Tovkal commented Apr 21, 2020

Thank you! Super helpful

@canberkozcelik

This comment has been minimized.

Copy link

canberkozcelik commented May 13, 2020

might it be calculating indexOfCharacter wrongly?
I'm clicking the very end of the underlined text "User agreement":
textRange NSRange location=42, length=10
indexOfCharacter Int 56

@leoiphonedev

This comment has been minimized.

Copy link
Owner Author

leoiphonedev commented May 13, 2020

Yes its calculating wrong, please check the updated code here

might it be calculating indexOfCharacter wrongly?
I'm clicking the very end of the underlined text "User agreement":
textRange NSRange location=42, length=10
indexOfCharacter Int 56

@canberkozcelik

This comment has been minimized.

Copy link

canberkozcelik commented May 13, 2020

so you have basically added 4 to indexOfCharacter? I don't think it's the right solution.

@leoiphonedev

This comment has been minimized.

Copy link
Owner Author

leoiphonedev commented May 13, 2020

@canberkozcelik

This comment has been minimized.

Copy link

canberkozcelik commented May 13, 2020

It's reasonable 👍 just for the ones having multiline text with 4-5 text links in it, do not choose this approach

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.