【问题标题】:Get text range of link in UITextView在 UITextView 中获取链接的文本范围
【发布时间】:2015-02-18 22:39:23
【问题描述】:

我有一个 UITextView,其中包含一个链接和一些其他文本。链接检测已启用并正常工作(iOS8)。但是,我无法在 textView 中找到链接的范围。

这个想法是扫描文本(在完成链接检测之后)并将链接预加载到 Web 视图中,这样当用户在某处点击元素时,Web 视图可以显示自己。

如何在 UITextView 中获取检测到的链接范围?

【问题讨论】:

  • 您是否有特定原因要预加载它?
  • 您是如何将链接放入NSAttributedString 的?您可以列举NSAttributedString 的属性并找到带有NSLinkAttributeName 的属性。但是您是在寻找它的范围还是它背后的链接 URL?
  • @AdamPro13 为了减少在本地打开它的延迟,而不是打开 safari 并在那里查看它。 @Larme 链接是 UITextView 自动检测到的,我没有创建属性字符串。有没有办法可以追溯枚举属性字符串?
  • 澄清一下,我正在寻找链接,我想的范围是从文本中提取它的一个步骤
  • developer.apple.com/library/ios/documentation/Cocoa/Reference/…: 可以用这个来查找链接吗?但是,链接属性是什么样的

标签: ios objective-c uitextview nsattributedstring


【解决方案1】:

如果您的目标是像 Twitter 如何打开推文中的链接,请执行以下操作:

  1. UITextView 的代理设置为您的视图控制器。
  2. 在您的视图控制器中实现UITextViewDelegate 方法textView:shouldInteractWithURL:inRange:。当用户在文本视图中选择链接时,这将被调用。在该方法中,您将需要return NO。但是,在返回 NO 之前,您应该创建一个具有 Web 视图的新视图控制器,并使用作为参数传入的 URL 加载 Web 视图。

这不会像您提到的那样进行预加载,但我不确定您是否出于特定原因(例如您希望 Web 视图与文本视图一起显示)或者您想要这样做只是因为你认为一旦用户点击链接就会有性能优势。

【讨论】:

  • 这是一个很好的答案。是的,主要是链接不是唯一的目标区域。我正在设计类似于移动版 Reddit 的东西,所以我也想依靠像整个 tableviewcell 这样的东西来打开它。
【解决方案2】:

一种方法是使用enumerateAttribute:inRange:options:usingBlock:,在我的示例中attr[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

编辑:
从您的 cmets 来看,我可能会假设您提到的链接是因为 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]];
}];

【讨论】:

  • 哇,太棒了,我有时间试试这个,我会告诉你的,但是快速测试表明它完全符合我的需要
  • 这正是我需要的答案。谢谢!虽然数据检测器是指属性字符串? NSDataDetector 没有方法
  • @MichaelLorenzo:我添加了更多信息。
猜你喜欢
  • 1970-01-01
  • 2013-03-15
  • 2014-10-08
  • 2011-08-29
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
相关资源
最近更新 更多