2015-02-18 2 views
1

У меня есть UITextView, который содержит ссылку и другой текст. Обнаружение ссылок включено и работает (iOS8). Тем не менее, я теряю, чтобы найти диапазон ссылки внутри textView.Получить текстовый диапазон ссылок в UITextView

Идея состоит в том, что текст сканируется (после того, как обнаружено соединение) и ссылка предварительно загружена в веб-представление, так что когда пользователь нажимает на элемент где-то, веб-просмотр может проявляться.

Как я могу получить диапазон обнаруженной ссылки в UITextView?

+0

Есть ли конкретная причина вы хотите предварительно загрузить его? – AdamPro13

+0

Как вы поместили ссылку в 'NSAttributedString'? Вы можете перечислить атрибуты вашего 'NSAttributedString' и найти тот, у которого есть' NSLinkAttributeName'. Но вы ищете его диапазон или URL-адрес ссылки за ним? – Larme

+0

@ AdamPro13 Чтобы уменьшить задержку при открытии ее локально, вместо открытия сафари и просмотра там. @ Larme Ссылка была автоматически обнаружена UITextView, я не создал атрибутированную строку. Есть ли способ, которым я могу ретроактивно перечислить атрибутированную строку? –

ответ

1

Способ сделать это, использовать enumerateAttribute:inRange:options:usingBlock:, где из моего примера 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); 

Я держал диапазон тоже, на всякий случай, но вы можете использовать NSArray со всеми различными ссылками, а не одного NSDictionary.

EDIT:
Из ваших комментариев, я могу предположить, что ссылка, которую вы упомянули там из-за NSDataDetector. В нескольких словах он обнаружит от NSString, если есть что-то вроде: «http://www.randomSite.com». Вы можете прочитать о NSDataDetector, чтобы получить дополнительную информацию об этом (он может определять номера телефонов, почтовые адреса и т. Д.), UITextView часто обнаруживают некоторые по умолчанию. Таким образом, NSAttributedString может не включать атрибут NSLinkAttributeName.

Так работа вокруг (на этот раз, я просто сохранил ссылку, но я думаю, вы знаете, как это сделать, если вы хотите что-то подобное предыдущее решение с диапазоном тоже):

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

Ничего себе, это здорово, я просто успел попробовать это, я дам вам знать, но быстрый тест говорит, что он делает именно то, что мне нужно –

+0

Это отвечает именно тому, что мне нужно. Спасибо! Хотя с помощью детектора данных вы подразумеваете строку с атрибутом? Нет никакого метода для NSDataDetector –

+0

@MichaelLorenzo: Я добавил дополнительную информацию. – Larme

1

Если вы стремитесь сделать что-то подобное, как Twitter открывает ссылки в твитах, сделайте следующее:

  1. Установите делегат для вашего UITextView к контроллеру представления.
  2. Внесите метод UITextViewDelegatetextView:shouldInteractWithURL:inRange: в ваш контроллер. Это вызывается, когда пользователь выбирает ссылку в текстовом представлении. В этом методе вы захотите return NO. Однако перед возвратом NO вы должны создать новый контроллер представления, который имеет веб-представление и загружает веб-представление с URL-адресом, который передается в качестве параметра.

Это не предварительная загрузка, как вы упомянули, но я не уверен, что вы делаете это по определенной причине (например, хотите, чтобы веб-представление отображалось рядом с текстовым представлением) или вы хотите сделать это только потому, что вы думаете, что будет преимущество в производительности, как только пользователь ударит ссылку.

+0

Это отличный ответ. Да, в основном, ссылка не является единственной целевой областью. Я разрабатываю нечто похожее на мобилизованный Reddit, поэтому я хочу полагаться на что-то вроде цельной таблицы, чтобы открыть ее. –

Смежные вопросы