Skip to content

Instantly share code, notes, and snippets.

@ycui1
Last active December 28, 2019 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ycui1/485c7891133b34237e0c66616eef41a9 to your computer and use it in GitHub Desktop.
Save ycui1/485c7891133b34237e0c66616eef41a9 to your computer and use it in GitHub Desktop.
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