Get text range of link in UITextView

后端 未结 2 906
忘掉有多难
忘掉有多难 2021-01-21 12:41

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 te

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-21 13:35

    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]];
    }];
    

提交回复
热议问题