Prior to Xcode 9 and iOS 11 I had a UITextView
within a UITableViewCell
that contained multiple links. Each link worked as expected, however since
Turns out there wasn't a problem after all. Changes in the way UITextView responds to touches in iOS11 means that clicking links requires more of a press rather than just a tap which previously worked in iOS10. I think this may be something to do with the fact that in iOS11 you can now press links and drag them which also displays details of URL. So a firmer press is needed for the UITextView to register the link being tapped.
Specifically in iOS 11.0 and 11.1 (not later in 11.2+, not earlier in 10.x), textView(_:shouldInteractWith:in:interaction)
from UITextViewDelegate is called from an interaction with a UILongPressGestureRecognizer
instead of a UITapGestureRecognizer
.
For those two iOS versions, user needs a small delay long press instead of a tap for a native interaction with UITextView links.
If the callback doesn't get called at all for those two iOS versions, even on a long press, you've likely been messing with gesture recognizers by subclassing your UITextView and overriding gestureRecognizerShouldBegin(_)
to return false
when it shouldn't.
Here is an example of quick partial workaround for gestureRecognizerShouldBegin(_)
that will disable loupe/magnifier long press (if that's the desired intent of the override), but still allow long press on links:
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer is UIPanGestureRecognizer {
// required for compatibility with isScrollEnabled
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer,
tapGestureRecognizer.numberOfTapsRequired == 1 {
// allowing taps for links
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
if let longPressGestureRecognizer = gestureRecognizer as? UILongPressGestureRecognizer,
// allowing small delay long press for links (required for iOS 11.0-11.1)
// average comparison value is used to distinguish between:
// 0.12 (smallDelayRecognizer)
// 0.5 (textSelectionForce and textLoupe)
longPressGestureRecognizer.minimumPressDuration < 0.325 {
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
gestureRecognizer.isEnabled = false
return false
}
An alternative is to fully disallow both UILongPressGestureRecognizer
and UITapGestureRecognizer
except for a self-made UITapGestureRecognizer that you would have build yourself to interact with links.