【问题标题】:Change attributes of one link in UITextView更改 UITextView 中一个链接的属性
【发布时间】:2015-04-06 12:08:18
【问题描述】:

我有一个带有多个 URL 的 UITextView,我通过将 dataDetectorTypes 属性设置为 UIDataDetectorTypeLink 来激活这些 URL。然后我使用linkTextAttributes 属性来设置链接的颜色。现在,当用户点击其中一个链接(使用UITapGestureRecognizer)时,我只想更改该链接的颜色。如果我更改linkTextAttributes,所有链接都会改变颜色。

如何仅更改被点击链接的颜色?

【问题讨论】:

    标签: ios objective-c uitextview


    【解决方案1】:

    如果这些网址是固定的。 例如: 我有以下网址:

    我会把它们放到一个 NSAttributedString 使用 NSMutableAttributedString 将它们全部组合起来

    NSMutableAttributedString *urlsAttributedText = [[NSMutableAttributedString alloc]init];
    
    NSAttributedString *url1 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.123.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
    
    NSAttributedString *url2 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.456.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor greenColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
    
    NSAttributedString *url3 = [[NSAttributedString alloc]initWithString:NSLocalizedString(@"http://www.789.com\n", nil) attributes:@{NSForegroundColorAttributeName : [UIColor redColor], NSFontAttributeName : [UIFont systemFontOfSize:15.0f]}];
    
    [urlsAttributedText url1];
    [urlsAttributedText appendAttributedString:url2];
    [urlsAttributedText appendAttributedString:url3];
    
    self.texView.attributedText = urlsAttributedText;
    

    干杯!

    【讨论】:

    • 不确定这如何让我更改所选网址的颜色。此外,网址已经在 NSString 中,这是我的 CoreData 模型的一部分,所以我认为我不能使用 appendAttributedString: 等来构造 NSMutableAttributedString
    • UITextView 上基本上没有链接属性可以改变访问的链接。 (check here) 但是有一个 UITextView 的委托可以捕获点击的 URL。这个想法是让这些字符串重新分配给 UITextView。否则只需使用 UIWebView 然后格式化 HTML 字符串,我认为这是一个更难的解决方案。
    • 是的,我之前看过shouldInteractWithURL:,但效果不佳,我切换到手势识别器。但我会重新审视它,因为它听起来是一个改变颜色的好地方。
    • 编码愉快!祝你有美好的一天!
    【解决方案2】:

    我想我解决了这个问题,使用了一个名为 UITextView 的子类,它有一个 rangeOfLink 属性。

    首先,在我的UIViewControllerviewDidLoad:,我添加

    self.textView.dataDetectorTypes = UIDataDetectorTypeLink; // change for other link types
    self.textView.selectable = YES;
    self.textView.userInteractionEnabled = YES;
    
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(handleTap:)];
    tapGesture.cancelsTouchesInView = YES;
    
    [self.textView addGestureRecognizer: tapGesture];
    [self.textView setNeedsDisplay]; // force a redraw so that drawRect is called
    

    然后在handleTap,我这样做:

    MyTextViewWithLink *aTextView = (IDTextViewWithLink *) recognizer.view;
    
    if (aTextView != self.textView)
        return;
    
    if (recognizer.state == UIGestureRecognizerStateEnded)
    {
        CGPoint location = [recognizer locationInView: aTextView];
    
     // this returns an NSTextCheckingResult if location is inside a link
        NSTextCheckingResult *result = [self textCheckingResultAtPoint: location inTextView: aTextView]; 
    
        if (result)
        {
            aTextView.rangeOfLink = result.range;
            [aTextView setNeedsDisplay]; // this will force the color change
    
            // open url
        }
    }
    

    最后我在我的UITextView 子类中覆盖drawRect

    self.linkTextAttributes = [NSDictionary dictionary];
    
    NSError *error = nil;
    NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes: NSTextCheckingTypeLink error: &error];  // change for other link types
    
    if (!error && dataDetector)
    {
        NSArray* resultString = [dataDetector matchesInString: self.text
                                                  options: NSMatchingReportProgress
                                                    range: NSMakeRange(0, [self.text length])];
        if (resultString.count > 0)
        {
            NSMutableAttributedString *mas = [self.attributedText mutableCopy];
    
            for (NSTextCheckingResult* result in resultString)
            {
                if (result.resultType == NSTextCheckingTypeLink)
                {
                    NSRange intersection = NSIntersectionRange(result.range, self.rangeOfLink);
    
                    if (intersection.length <= 0) // no match
                        [mas addAttribute: NSForegroundColorAttributeName
                                    value: [UIColor blueColor]
                                    range: self.rangeOfLink];
                    else
                        [mas addAttribute: NSForegroundColorAttributeName
                                    value: [UIColor redColor]
                                    range: self.rangeOfLink];
                }
            }
    
            self.attributedText = mas;
        }
    }
    
    [super drawRect: rect];
    

    现在如果 textView 有多个链接,只有选中的链接会改变颜色。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多