Skip to content

Instantly share code, notes, and snippets.

@dezinezync
Last active October 1, 2019 04:24
Show Gist options
  • Save dezinezync/10d5326aabded2f1565d5b56fe1ed560 to your computer and use it in GitHub Desktop.
Save dezinezync/10d5326aabded2f1565d5b56fe1ed560 to your computer and use it in GitHub Desktop.
Link Detection fires immediately in iOS 13.x on UITextView
/*
* The issue this whole time was the UITextView would not wait for the pan gesture of it's hosting UIScrollView to fail.
* Once we find out the correct gestures to hook into, we can ensure they don't get recognized simultaneously.
*/
@interface TextViewSubclass : UITextView <UIGestureRecognizerDelegate> {
BOOL _hasHookedGesturesForiOS13LinkTapBug;
}
- (void)_hookGestures;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
@end
@implementation TextViewSubclass
- (void)_hookGestures {
/*
* as this can get called multiple times, we use a simple flag to keep it in check.
*/
if (_hasHookedGesturesForiOS13LinkTapBug) {
return;
}
_hasHookedGesturesForiOS13LinkTapBug = YES;
Class longPress = UILongPressGestureRecognizer.class;
Class linkTap = UITapGestureRecognizer.class;
for (UIGestureRecognizer *gesture in self.gestureRecognizers) {
if ([gesture isKindOfClass:longPress] || [gesture isKindOfClass:linkTap]) {
gesture.delegate = self;
}
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
Class longPress = UILongPressGestureRecognizer.class;
Class linkTap = UITapGestureRecognizer.class;
Class scrollViewPan = NSClassFromString(@"UIScrollViewPanGestureRecognizer");
if ([gestureRecognizer isKindOfClass:longPress] || [gestureRecognizer isKindOfClass:linkTap]) {
#ifdef DEBUG
NSLog(@"Other gesture: %@", otherGestureRecognizer);
#endif
if ([otherGestureRecognizer isKindOfClass:scrollViewPan]) {
return NO;
}
return YES;
}
return YES;
}
#pragma mark - Usage
- (void)setAttributedText:(NSAttributedString *)attributedText {
[super setAttributedText:attributedText];
// we only need to call this on iOS 13.
if (@avilable(iOS 13, *)) {
[self _hookGestures];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment