48 lines
1.6 KiB
Swift
48 lines
1.6 KiB
Swift
//
|
|
// UITapGesture.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 8/4/22.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
extension UITapGestureRecognizer {
|
|
|
|
public func didTapAttributedTextInLabel(_ label: UILabel, inRange targetRange: NSRange) -> Bool {
|
|
|
|
guard let abstractContainer = label.abstractTextContainer() else { return false }
|
|
let textContainer = abstractContainer.0
|
|
let layoutManager = abstractContainer.1
|
|
|
|
let tapLocation = location(in: label)
|
|
let indexOfGlyph = layoutManager.glyphIndex(for: tapLocation, in: textContainer)
|
|
let intrinsicWidth = label.intrinsicContentSize.width
|
|
|
|
// Assert that tapped occured within acceptable bounds based on alignment.
|
|
switch label.textAlignment {
|
|
case .right:
|
|
if tapLocation.x < label.bounds.width - intrinsicWidth {
|
|
return false
|
|
}
|
|
case .center:
|
|
let halfBounds = label.bounds.width / 2
|
|
let halfIntrinsicWidth = intrinsicWidth / 2
|
|
|
|
if tapLocation.x > halfBounds + halfIntrinsicWidth {
|
|
return false
|
|
} else if tapLocation.x < halfBounds - halfIntrinsicWidth {
|
|
return false
|
|
}
|
|
default: // Left align
|
|
if tapLocation.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(tapLocation) && NSLocationInRange(indexOfGlyph, targetRange)
|
|
}
|
|
}
|