Ios UITextView中链接的不同样式

Ios UITextView中链接的不同样式,ios,objective-c,uitextview,nsattributedstring,Ios,Objective C,Uitextview,Nsattributedstring,我希望我的UITextView包括纯文本、链接、电话号码和其他UIDataDetectorTypes。例如,纯文本-黑色,链接-带下划线的蓝色,标签-绿色。因此,我解析文本并添加到hashtags的链接: [attributedString addAttribute:NSLinkAttributeName value:[NSString stringWithFormat:@"hashtag://%@", hashtag] range:range]; 如果dataDetectorTypes设置为

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

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

如果
dataDetectorTypes
设置为
UIDataDetectorTypeAll
,则默认情况下会检测到其他链接。但是如何更改hashtags的链接样式呢?

您需要找到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];
    }];
}

您可以使用官方的Twitter库来跟踪与一起调用的hashtag

hashtag有特殊的条件,这些条件可能不止是字母数字字符加上#

twitter文本库将自动为您找到hashtag的范围,然后您应该能够使用tttatAttributedLabel对其进行格式化

下面是两个库的一个示例实现

- (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];

谢谢,我查过了。但是,如果使用UIExtView而不是UILabel,这可能吗?是的,这是可能的。我回答的要点是关于Twitter的官方库,它将帮助您检测hashtags。一旦检测到它们,在UITextView上找到设置哈希标记样式的解决方案将比找到跟踪哈希标记的解决方案更容易。搜索哈希标记可以通过不带任何库的正则表达式来解决。现在的主要问题是
UITextView
linktexttributes
覆盖了属性字符串中的所有自定义属性(如果它包含
NSLinkAttributeName
属性)。你有什么想法吗?是的,它可以通过正则表达式来解决。但是,可以建议使用多少个正则表达式来跟踪hashtag。我的解决方案是建议使用更统一/标准的解决方案来跟踪hashtag,Twitter之后的一种。要在UITextView上使用它,您可以遵循检测哈希标记范围并将样式应用到这些范围的逻辑。问题是
UITextView的属性
linkTextAttributes
覆盖属性字符串中的所有自定义属性,如果是包含
NSLinkAttributeName
属性。
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];
                             }
                         }];
}