Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import UIKit
- class LabelTappable: UILabel {
- let layoutManager = NSLayoutManager()
- let textContainer = NSTextContainer(size: CGSize.zero)
- let tapGesture = UITapGestureRecognizer()
- var textStorage = NSTextStorage() {
- didSet {
- textStorage.addLayoutManager(layoutManager)
- }
- }
- var didTap: ((_ label: UILabel, _ characterIndex: Int) -> Void)?
- override var attributedText: NSAttributedString? {
- didSet {
- if let attributedText = attributedText {
- textStorage = NSTextStorage(attributedString: attributedText)
- } else {
- textStorage = NSTextStorage()
- }
- }
- }
- override var lineBreakMode: NSLineBreakMode {
- didSet {
- textContainer.lineBreakMode = lineBreakMode
- }
- }
- override var numberOfLines: Int {
- didSet {
- textContainer.maximumNumberOfLines = numberOfLines
- }
- }
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- setUp()
- }
- override init(frame: CGRect) {
- super.init(frame: frame)
- setUp()
- }
- func setUp() {
- isUserInteractionEnabled = true
- layoutManager.addTextContainer(textContainer)
- textContainer.lineFragmentPadding = 0
- textContainer.lineBreakMode = lineBreakMode
- textContainer.maximumNumberOfLines = numberOfLines
- tapGesture.addTarget(self, action: #selector(LabelTappable.labelTapped(_:)))
- addGestureRecognizer(tapGesture)
- }
- override func layoutSubviews() {
- super.layoutSubviews()
- textContainer.size = bounds.size
- }
- @objc func labelTapped(_ gesture: UITapGestureRecognizer) {
- guard gesture.state == .ended else {
- return
- }
- let locationOfTouch = gesture.location(in: gesture.view)
- let textBoundingBox = layoutManager.usedRect(for: textContainer)
- let textContainerOffset = CGPoint(
- x: (bounds.width - textBoundingBox.width) / 2 - textBoundingBox.minX,
- y: (bounds.height - textBoundingBox.height) / 2 - textBoundingBox.minY
- )
- let locationOfTouchInTextContainer = CGPoint(
- x: locationOfTouch.x - textContainerOffset.x,
- y: locationOfTouch.y - textContainerOffset.y
- )
- let characterIndex = layoutManager.characterIndex(for: locationOfTouchInTextContainer,
- in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
- /* HOW TO USE */
- /*
- es for links
- self.didTap = { [weak self] label, characterIndex in
- guard let _ = self else {
- return
- }
- if let url = label.attributedText?.attribute(.link, at: characterIndex, effectiveRange: nil) as? URL, UIApplication.shared.canOpenURL(url) {
- UIApplication.shared.open(url, options: [:], completionHandler: nil)
- }
- }
- */
- didTap?(self, characterIndex)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement