【问题标题】:Different styles for links in a UITextViewUITextView 中链接的不同样式
【发布时间】:2015-03-24 09:10:16
【问题描述】:

我希望我的 UITextView 包含纯文本、链接、电话号码和其他 UIDataDetectorTypes。例如,纯文本 - 黑色,链接 - 蓝色带下划线,主题标签 - 绿色。因此,我解析文本并添加指向主题标签的链接:

[attributedString addAttribute:NSLinkAttributeName value:[NSString stringWithFormat:@"hashtag://%@", hashtag] range:range];

如果dataDetectorTypes 设置为UIDataDetectorTypeAll,则默认检测其他链接。但是如何更改主题标签的链接样式?

【问题讨论】:

    标签: ios objective-c uitextview nsattributedstring


    【解决方案1】:

    您可以使用官方 Twitter 库来跟踪名为 twitter textTTTAttributedLabel 的主题标签。

    主题标签有特殊条件,这些条件可能不仅仅是以#开头的字母数字字符。

    twitter-text 库会自动为您找到主题标签的范围,然后您应该能够使用 TTTAttributedLabel 对其进行格式化。

    这是两个库的示例实现。

    - (void)scanForHashtag:(NSArray *)hashtags fromLabel:(id)sender
    {
        TTTAttributedLabel *label = (TTTAttributedLabel *)sender;
    
        for (TwitterTextEntity *entity in hashtags) {
            UIFont *boldSystemFont = [UIFont fontWithName:@"Helvetica-Bold" size:12];
            CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)boldSystemFont.fontName, boldSystemFont.pointSize, NULL);
            NSArray *keys = [[NSArray alloc] initWithObjects:(id)kCTForegroundColorAttributeName,(id)kCTUnderlineStyleAttributeName,(NSString *)kCTFontAttributeName, nil];
            UIColor *hashtagColor;
            hashtagColor = [UIColor greenColor];
            NSArray *objects = [[NSArray alloc] initWithObjects:hashtagColor,[NSNumber numberWithInt:kCTUnderlineStyleNone],(__bridge id)font, nil];
            NSDictionary *linkAttributes = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
            label.linkAttributes = linkAttributes;
    
            NSString *hashtag = [label.text substringWithRange:entity.range];
    
            if (entity.type == 2) { //Hashtag
                [label addLinkToPhoneNumber:hashtag withRange:entity.range];
            } else if (entity.type == 0) { //URL
                NSURL *url = [NSURL URLWithString:[label.text substringWithRange:entity.range]];
                [label addLinkToURL:url withRange:entity.range];
            }
        }
    }
    
    - (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithPhoneNumber:(NSString *)phoneNumber
    {
    
        //Do whatever you need when the hashtag is tapped.
    }
    
    [self scanForHashtag:[TwitterText hashtagsInText:@"The text that contains the tweet with hashtags." checkingURLOverlap:NO] fromLabel:yourLabel]; //yourLabel is the label that contains the text so it would be formatted.
    

    编辑 UITextView

    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:str];
    [attributedString addAttribute:NSBackgroundColorAttributeName
                       value:[UIColor yellowColor]
                       range:entity.range];
    

    【讨论】:

    • 谢谢,我已经检查过了。但是 UITextView 不是 UILabel 有可能吗?
    • 是的,这是可能的。我的回答主要是关于 Twitter 的官方库,它可以帮助您检测主题标签。一旦你检测到他们找到一个解决方案来设置你的 UITextView 上的主题标签的样式,这将比必须找到一个跟踪主题标签的解决方案更容易。
    • 搜索主题标签是通过没有任何库的正则表达式来解决的。现在的主要问题是UITextViewlinkTextAttributes 会覆盖属性字符串中的所有自定义属性,如果它包含NSLinkAttributeName 属性。你有什么想法吗?
    • 是的,可以通过正则表达式解决。但是,可以建议使用多少正则表达式来跟踪主题标签。我的解决方案是建议使用更统一/标准的解决方案来跟踪主题标签,即 Twitter 之后的解决方案。
    • 要在 UITextView 上使用它,您可以遵循检测标签范围并将样式应用到这些范围的逻辑。
    【解决方案2】:

    您需要找到 hashtags 范围,然后为它们添加特殊属性。 例如。

    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"YOUR HASHTAG PATTERN" options:0 error:&error];
    if (!error) {
        [regex enumerateMatchesInString:messageText options:0 range:NSMakeRange(0, messageText.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
            [mutableAttributedString addAttributes:@{
                                                   NSFontAttributeName: [UIFont fontLinkMessageCell],
                                                   (__bridge NSString*) kCTForegroundColorAttributeName: [UIColor colorLinkOutCell],
                                                   NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone),
                                                   } range:result.range];
        }];
    }
    

    【讨论】:

    • 问题是UITextView 的属性linkTextAttributes 覆盖属性字符串中的所有自定义属性,如果它包含NSLinkAttributeName 属性。
    【解决方案3】:
    self.textView.linkTextAttributes = @{};
    self.textView.textStorage.delegate = self;
    
    - (void) textStorage: (NSTextStorage*) textStorage didProcessEditing: (NSTextStorageEditActions) editedMask range: (NSRange) editedRange changeInLength: (NSInteger) delta
    {
        [textStorage enumerateAttribute: NSLinkAttributeName
                                inRange: editedRange
                                options: 0
                             usingBlock: ^(id value, NSRange range, BOOL* stop)
                             {
                                 if (value)
                                 {
                                     [textStorage addAttribute: NSForegroundColorAttributeName
                                                         value: [UIColor redColor]
                                                         range: range];
                                 }
                             }];
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-05
      • 2017-05-01
      • 1970-01-01
      • 2018-09-27
      • 2014-02-21
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      相关资源
      最近更新 更多