Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
extension UILabel {
func characterIndexTapped(tap: UITapGestureRecognizer) -> Int? {
guard attributedText != nil else { return nil }
// Create instances for NSLayoutManager, NSTextContainer, and NSTextStorage
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: .zero)
let textStorage = NSTextStorage(attributedString: attributedText!)
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
textContainer.lineFragmentPadding = 0
textContainer.lineBreakMode = lineBreakMode
textContainer.maximumNumberOfLines = numberOfLines
// Calculate the tap location in terms of character index
let location = tap.location(in: self)
let size = bounds.size
let textBoundingBox = layoutManager.usedRect(for: textContainer)
let textContainerOffset = CGPoint(x: (size.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, y: (size.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y)
let locationOfTouchInTextContainer = CGPoint(x: location.x - textContainerOffset.x, y: location.y - textContainerOffset.y)
return layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment