54 lines
1.9 KiB
Swift
54 lines
1.9 KiB
Swift
//
|
|
// 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)
|
|
}
|
|
}
|