'SwiftUI: How to check for a UITextRangeView?

I am using the auto keyboard dismiss SwiftUI code from How to hide keyboard when using SwiftUI?

Under AnyGestureRecognizer, I'll like to cancel when the touch is still within the UITextView or if it is on a selected Text within a SwiftUI TextField (e.g. that user can drag to select a wider range of the text).

I've noticed that when I tap on the selected text (i.e. 'consequent' in the image below which is already selected), the touchesBegan function returns 'state = .began'. And touches.first?.view is returned as

▿ Optional<UIView>
  - some : <UITextRangeView: 0x104f0b750; frame = (0 0; 0 0); opaque = NO; gestureRecognizers = <NSArray: 0x2832778a0>; layer = <CALayer: 0x283c06440>> 

I tried to check if add a if statement to check if touches.first?.view is a UITextRange but it returns nil. How can I check for a UITextRangeView?. Thanks!

enter image description here



Solution 1:[1]

I fix the issue with selecting text with drag with the changes to the AnyGestureRecognizer

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
    if let touchedView = touches.first?.view, touchedView is UIControl {
        state = .cancelled

    } else if let touchedView = touches.first?.view as? UITextView, touchedView.isEditable {
        state = .cancelled

    } else {
        
        if var touchedView = touches.first?.view {
            while let superview = touchedView.superview {
                if let view = superview as? UITextView, view.isEditable {
                    state = .cancelled
                    return
                } else {
                    touchedView = superview
                }
            }
        }
        
        state = .began
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user14341201