Reputation: 4667
I have an UITextView
with attributed text which is set up like this:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is a message.\nClick here for more info"];
textView.linkTextAttributes = @{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)};
NSRange linkRange = [attributedString.string rangeOfString:@"Click here for more info"];
[attributedString addAttribute:NSLinkAttributeName value:@"" range:linkRange];
textView.attributedText = attributedString;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(infoTapped:)];
[textView addGestureRecognizer:tapRecognizer
Then I catch a tap like this:
- (void)infoTapped:(UITapGestureRecognizer *)tapGesture {
if (tapGesture.state != UIGestureRecognizerStateEnded) {
return;
}
UITextView *textView = (UITextView *)tapGesture.view;
CGPoint tapLocation = [tapGesture locationInView:textView];
UITextPosition *textPosition = [textView closestPositionToPoint:tapLocation];
NSDictionary *attributes = [textView textStylingAtPosition:textPosition inDirection:UITextStorageDirectionForward];
NSString *link = attributes[NSLinkAttributeName];
if (link) {
// Do stuff
}
}
In iOS 10 this works fine and I am able to detect the NSLinkAttributeName
attribute.
However, in iOS 9 the call to [textView closestPositionToPoint:tapLocation]
returns nil
and I am not able to do anything from there on.
Btw. My textview has both editable
and selectable
set to NO. I know some say that selctable
needs to be set to YES, but I am not sure it's true. First of all, it works fine without selectable in iOS 10. Second, if I do set it to selectable it does work, but only sort of. I do get the tap in iOS 9, but it only works erratically (in both 9 and 10). Sometimes it registers the tap and sometimes it doesn't. Basically, when I see the link highlight like when you click a link in a browser it doesn't register. Furthermore, the text in the text view can now be selected which I do not want.
Upvotes: 1
Views: 3341
Reputation: 451
Why do you want to select links using tap gesture? UITextView has perfect links recognition feature. I can't answer why your solution doesn't work properly on iOS 9 but I can suggest you to handle links in another way. This will work on iOS 9 as well.
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"This is a message.\nClick here for more info" attributes:nil];
NSRange range = [str.string rangeOfString:@"Click here for more info"];
// add a value to link attribute, you'll use it to determine what link is tapped
[str addAttribute:NSLinkAttributeName value:@"ShowInfoLink" range:range];
self.textView.linkTextAttributes = @{NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle)};
self.textView.attributedText = str;
// set textView's delegate
self.textView.delegate = self;
Then implement link related method of UITextViewDelegate:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction
{
if ([URL.absoluteString isEqualToString:@"ShowInfoLink"]) {
// Do something
}
return NO;
}
To make it works you have to set selectable = YES and check links flag in storyboard to be able detect links.
Upvotes: 6