// // UITapGesture.swift // VDS // // Created by Matt Bruce on 8/4/22. // import Foundation import UIKit extension UITapGestureRecognizer { /// Determines if the touch event has a action attribute within the range given /// - Parameters: /// - label: UILabel in question /// - targetRange: Range to look within /// - Returns: Wether the range in the label has an action public func didTapActionInLabel(_ label: Label, inRange targetRange: NSRange) -> Bool { guard let abstractContainer = label.abstractTextContainer() else { return false } let location = location(in: label) let textContainer = abstractContainer.textContainer let layoutManager = abstractContainer.layoutManager let indexOfGlyph = layoutManager.glyphIndex(for: location, in: textContainer) let intrinsicWidth = label.intrinsicContentSize.width // Assert that tapped occured within acceptable bounds based on alignment. switch label.textAlignment { case .right: if location.x < label.bounds.width - intrinsicWidth { return false } case .center: let halfBounds = label.bounds.width / 2 let halfIntrinsicWidth = intrinsicWidth / 2 if location.x > halfBounds + halfIntrinsicWidth { return false } else if location.x < halfBounds - halfIntrinsicWidth { return false } default: // Left align if location.x > intrinsicWidth { return false } } // Affirms that the tap occured in the desired rect of provided by the target range. return layoutManager.boundingRect(forGlyphRange: targetRange, in: textContainer).contains(location) && NSLocationInRange(indexOfGlyph, targetRange) } }