【问题标题】:Unable get range from NSString for NSURL absoluteString无法从 NSString 获取 NSURL absoluteString 的范围
【发布时间】:2018-09-03 01:02:15
【问题描述】:

我正在开发聊天应用程序,其中必须检测输入的文本是否是其 URL。如果是这样,请更改其颜色并在其下划线。请看下面的截图:

要更改网址的颜色,我使用了以下代码:

NSString *urlString = [[detetctedURL absoluteString] stringByRemovingPercentEncoding];

            /* *detetctedURL is detected url from entered text using NSDataDetector
            /* *for messageText http://stackoverflow.com/somefolder/any-[thing]-etc, the detectedURL is http://stackoverflow.com/somefolder/any-%5Bthing%5B-etc */

            NSRange r = [messageText rangeOfString:urlString];
            if (r.location != NSNotFound)
            {
                 //colorFromHex 4285f4
                 [atext addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:66.0/255.0 green:133.0/255.0 blue:244.0/255.0 alpha:1.0] range:r];
                 [atext addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:r];
                 //set attributed text (atext) to UILabel               
            }

如果 messageText 包含带有特殊字符和百分比编码的 URL,或者只有百分比编码,我如何正确格式化检测到的 URL?

谢谢!

更新:

在以下代码的帮助下,我能够获得所需的范围。但是,对于大多数链接来说,它几乎可以正常工作,但并非所有链接都像存在 ']-(' 之类的字符。

NSString *urlString = [url absoluteString];
        NSRange r = [messageText rangeOfString:urlString];
        BOOL foundRange = YES;
        if (r.location == NSNotFound)
        {
            foundRange = NO;
            //for umlauts or special characters
            urlString = [[url absoluteString] stringByRemovingPercentEncoding];
            r = [messageText rangeOfString:urlString];
            if (r.location == NSNotFound)
            {
                //for white space in url
                urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
                r = [messageText rangeOfString:urlString];

                if (r.location == NSNotFound)
                {
                    urlString = [url absoluteString];
                    NSString *prefix = url.scheme;
                    if(prefix)
                    {
                        prefix = [prefix stringByAppendingString:@"://"];
                        urlString = [urlString stringByReplacingOccurrencesOfString:prefix withString:@""];
                        r = [messageText rangeOfString:urlString];
                        if (r.location == NSNotFound)
                        {
                            urlString = [urlString stringByRemovingPercentEncoding];
                            r = [messageText rangeOfString:urlString];
                            if (r.location == NSNotFound)
                            {
                                urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
                                r = [messageText rangeOfString:urlString];
                                if (r.location != NSNotFound){ foundRange = YES; }
                            }else{ foundRange = YES; }
                        }else{ foundRange = YES; }
                    }
                }else{ foundRange = YES; }
            }else{ foundRange = YES; }
        }

        if (foundRange)
        {
            //colorFromHex 4285f4
            [atext addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:66.0/255.0 green:133.0/255.0 blue:244.0/255.0 alpha:1.0] range:r];

            [atext addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:r];

            myLabel.attributedText = atext; 
        }

【问题讨论】:

  • 这里有什么问题?您正在使用 stringByRemovingPercentEncoding 来实际删除百分比编码的 url 字符串?你想做什么?
  • 我希望将具有特殊字符和百分比的网址格式化为带下划线的蓝色。但问题是当我们使用 NSDatadetector 从字符串中检测 url 时,它通过添加百分比编码返回 url,即特殊字符被转义。在获取范围以格式化 url 时,我正在从 url 中删除百分比编码,将其传递以获取范围和格式。这仅在实际文本中有特殊符号时才有效。(附件截图中的案例 2)。但是当实际文本已经包含百分比编码数据时,我们如何确定呢?
  • 数据检测器会直接给你匹配范围。无需您自己搜索字符串。
  • @KenThomases 你是对的,但是我将无法根据要求格式化检测到的 url(检测到的 url 的颜色将为蓝色)。有没有办法为 NSDataDetector 检测到的 url 指定 textColor、italic 等属性?
  • @iAkki,为什么不能格式化?您可以使用数据检测器为您提供的范围,就像您尝试使用从 -rangeOfString: 获得的范围一样。

标签: ios object nsstring nsurl nsdatadetector


【解决方案1】:

使用NSDataDetector 查找并突出显示网址。

NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink 
                                                           error: nil];

NSArray* matches = [detector matchesInString: source 
                                     options: 0 
                                       range: NSMakeRange(0, [source length])];

您可以使用它来查找电话号码、地址等。

【讨论】:

    【解决方案2】:

    在您的文本视图上设置 .dataDetectorTypes,而不是尝试自己更改颜色。 UITextView 会自行突出显示。

    【讨论】:

    • 对不起,我正在使用 UILabel,由于一些限制,暂时无法更改。
    猜你喜欢
    • 2012-02-02
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多