Guest User

Untitled

a guest
Jan 16th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.62 KB | None | 0 0
  1. import Foundation
  2. import UIKit
  3.  
  4. class CustomLabel: UILabel {
  5.  
  6. let layoutManager = NSLayoutManager()
  7. let textContainer = NSTextContainer(size: CGSize.zero)
  8. var textStorage = NSTextStorage() {
  9. didSet {
  10. textStorage.addLayoutManager(layoutManager)
  11. }
  12. }
  13. var onCharacterTapped: ((_ label: UILabel, _ characterIndex: Int) -> Void)?
  14.  
  15. let tapGesture = UITapGestureRecognizer()
  16.  
  17. override var attributedText: NSAttributedString? {
  18. didSet {
  19. if let attributedText = attributedText {
  20. textStorage = NSTextStorage(attributedString: attributedText)
  21. } else {
  22. textStorage = NSTextStorage()
  23. }
  24. }
  25. }
  26. override var lineBreakMode: NSLineBreakMode {
  27. didSet {
  28. textContainer.lineBreakMode = lineBreakMode
  29. }
  30. }
  31.  
  32. override var numberOfLines: Int {
  33. didSet {
  34. textContainer.maximumNumberOfLines = numberOfLines
  35. }
  36. }
  37.  
  38. required init?(coder aDecoder: NSCoder) {
  39. super.init(coder: aDecoder)
  40. setUp()
  41. }
  42.  
  43. override init(frame: CGRect) {
  44. super.init(frame: frame)
  45. setUp()
  46. }
  47. func setUp() {
  48. isUserInteractionEnabled = true
  49. layoutManager.addTextContainer(textContainer)
  50. textContainer.lineFragmentPadding = 0
  51. textContainer.lineBreakMode = lineBreakMode
  52. textContainer.maximumNumberOfLines = numberOfLines
  53. tapGesture.addTarget(self, action: #selector(CustomLabel.labelTapped(_:)))
  54. addGestureRecognizer(tapGesture)
  55. }
  56.  
  57. override func layoutSubviews() {
  58. super.layoutSubviews()
  59. textContainer.size = bounds.size
  60. }
  61.  
  62. @objc func labelTapped(_ gesture: UITapGestureRecognizer) {
  63. guard gesture.state == .ended else {
  64. return
  65. }
  66. let locationOfTouch = gesture.location(in: gesture.view)
  67. let textBoundingBox = layoutManager.usedRect(for: textContainer)
  68. let textContainerOffset = CGPoint(x: (bounds.width - textBoundingBox.width) / 2 - textBoundingBox.minX,
  69. y: (bounds.height - textBoundingBox.height) / 2 - textBoundingBox.minY)
  70. let locationOfTouchInTextContainer = CGPoint(x: locationOfTouch.x - textContainerOffset.x, y: locationOfTouch.y - textContainerOffset.y)
  71. let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer,
  72. in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
  73.  
  74. onCharacterTapped?(self, indexOfCharacter)
  75. }
  76.  
  77. }
Add Comment
Please, Sign In to add comment