allow touch events for labels to bleed through

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-06-19 10:58:48 -05:00
parent 5efcc624e0
commit bdd481109a
2 changed files with 41 additions and 1 deletions

View File

@ -199,6 +199,20 @@ open class SelectorItemBase<Selector: SelectorControlable>: Control, Errorable,
accessibilityValue = accessibilityValueText accessibilityValue = accessibilityValueText
} }
/// Overriden to take the hit if there is an onClickSubscriber and the view is not a UIControl
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let labelPoint = convert(point, to: label)
let childLabelPoint = convert(point, to: childLabel)
if label.isAction(for: labelPoint) {
return label
} else if childLabel.isAction(for: childLabelPoint) {
return childLabel
} else {
return super.hitTest(point, with: event)
}
}
/// Resets to default settings. /// Resets to default settings.
open override func reset() { open override func reset() {
super.reset() super.reset()

View File

@ -383,13 +383,39 @@ open class Label: UILabel, ViewProtocol, UserInfoable {
@objc private func textLinkTapped(_ gesture: UITapGestureRecognizer) { @objc private func textLinkTapped(_ gesture: UITapGestureRecognizer) {
for actionable in actions { for actionable in actions {
// This determines if we tapped on the desired range of text. // This determines if we tapped on the desired range of text.
if gesture.didTapActionInLabel(self, inRange: actionable.range) { let location = gesture.location(in: self)
if didTapActionInLabel(location, inRange: actionable.range) {
actionable.performAction() actionable.performAction()
return return
} }
} }
} }
public func isAction(for location: CGPoint) -> Bool {
for actionable in actions {
if didTapActionInLabel(location, inRange: actionable.range) {
return true
}
}
return false
}
private func didTapActionInLabel(_ location: CGPoint, inRange targetRange: NSRange) -> Bool {
guard let attributedText else { return false }
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: bounds.size)
let textStorage = NSTextStorage(attributedString: attributedText)
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
let characterIndex = layoutManager.characterIndex(for: location, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
guard let _ = attributedText.attribute(NSAttributedString.Key.action, at: characterIndex, effectiveRange: nil) as? String, characterIndex < attributedText.length else { return false }
return true
}
private func customAccessibilityElement(text: String?, range: NSRange, accessibleText: String? = nil) -> AccessibilityActionElement? { private func customAccessibilityElement(text: String?, range: NSRange, accessibleText: String? = nil) -> AccessibilityActionElement? {
guard let text = text, let attributedText else { return nil } guard let text = text, let attributedText else { return nil }