Get text range of link in UITextView

为君一笑 提交于 2019-12-31 03:26:48

问题


I have a UITextView that contains a link and some other text. The link detection is enabled and working (iOS8). However, I am at loss to find the range of the link within the textView.

The idea is that the text is scanned (after link detection is done) and the link preloaded into a web view, so that when a user taps on an element somewhere, the web view can reveal itself.

How can I get the range of the detected link within a UITextView?


回答1:


A way to do it, is to use enumerateAttribute:inRange:options:usingBlock:, where from my example attr is [yourTextView attributedText].

__block NSMutableDictionary *ranges = [[NSMutableDictionary alloc] init];
[attr enumerateAttribute:NSLinkAttributeName
                 inRange:NSMakeRange(0, [attr length])
                 options:0
              usingBlock:^(id value, NSRange range, BOOL *stop) {
    NSLog(@"Attribute: %@, %@", value, NSStringFromRange(range));
                  if (value)
                      [ranges setObject:value forKey:[NSValue valueWithRange:range]];
}];
NSLog(@"Ranges: %@", ranges);

I kept the range too, just in case, but you could use a NSArray with all the different links instead of a NSDictionary.

EDIT:
From your comments, I may assume that the link you mentioned are there because of the NSDataDetector. In a few words, it will detect from NSString if there is something like: "http://www.randomSite.com". You can read about NSDataDetector to get more info about it (it can detect phone numbers, mail adresses etc.), the UITextView often detect some by defaults. So the NSAttributedString may not incorporate the NSLinkAttributeName attribute.

So a work around (this time, I just kept the link, but I guess you know how to do if you want something like previous solution with the range too):

NSString *stringWithNSDataDetector = [yourTextView text];
NSError *error = nil;
NSDataDetector * dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink
                                                                error:&error];
//Check if (error) before
__block NSMutableArray *allMatches = [[NSMutableArray alloc] init];
[dataDetector enumerateMatchesInString:stringWithNSDataDetector
                           options:0
                             range:NSMakeRange(0, [stringWithNSDataDetector length])
                        usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop)
{
    if ([match resultType] == NSTextCheckingTypeLink)
        [allMatches addObject:[match URL]];
}];



回答2:


If you're aiming to do something like how Twitter opens links in tweets, do the following:

  1. Set the delegate for your UITextView to your view controller.
  2. Implement the UITextViewDelegate method textView:shouldInteractWithURL:inRange: in your view controller. This will get called when the user selects the link in the text view. In the method, you will want to return NO. However, before returning NO you should create a new view controller that has a web view and load the web view with the URL that gets passed in as a parameter.

This doesn't do the preloading like you mentioned, but I'm not sure if you're doing it for a specific reason (like you want the web view to display alongside the text view) or you want to do it just because you think there will be a performance advantage once the user taps the link.



来源:https://stackoverflow.com/questions/28595378/get-text-range-of-link-in-uitextview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!