新浪微博客户端(56)-拼接微博内容中的昵称,超链接,表情图片

 

DJStatusPart.h

#import <Foundation/Foundation.h>

@interface DJStatusPart : NSObject

/** 文本块内容 */
@property (nonatomic,copy) NSString *text;
/** 文本块范围 */
@property (nonatomic,assign) NSRange range;
/** 当前文本块是否是特殊文本(昵称,超链接,Emoji) */
@property (nonatomic,assign,getter=isSpecial) BOOL isSpecial;
/** 当前文本块是否是表情图片 */
@property (nonatomic,assign,getter=isEmotion) BOOL isEmotion;

@end

DJStatus.m

// 设置带属性的文本内容
- (void)setText:(NSString *)text {

    _text = text;
    
    // 将微博内容文本转换为带属性的微博内容文本
    NSMutableAttributedString *attributedText = [self attributedTextWithText:text];
    [attributedText addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, attributedText.length)];
    
    // 行间距
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    [paragraphStyle setLineSpacing:2];
    [attributedText addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedText.length)];
    
    _attributedText = attributedText;
}



- (void)setRetweeted_status:(DJStatus *)retweeted_status {

    _retweeted_status = retweeted_status;
    
    DJUser *retwetedUser = retweeted_status.user;
    NSString *retweetedText = [NSString stringWithFormat:@"@%@: %@",retwetedUser.name,retweeted_status.text];
    
    // 将转发内容文本转换为带属性的微博内容文本
    NSMutableAttributedString *attributedText = [self attributedTextWithText:retweetedText];
    [attributedText addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:13] range:NSMakeRange(0, attributedText.length)];
    
    // 行间距
    NSMutableParagraphStyle *paragraphSytle = [[NSMutableParagraphStyle alloc] init];
    [paragraphSytle setLineSpacing:2];
    [attributedText addAttribute:NSParagraphStyleAttributeName value:paragraphSytle range:NSMakeRange(0, attributedText.length)];
    
    _retweetedAttributedText = attributedText;
    
}



/** 普通文本->属性文本 */
- (NSMutableAttributedString *)attributedTextWithText:(NSString *)text {
    
    // 表情的规则
    NSString *emotionPattern = @"\\[[0-9a-zA-Z\\u4e00-\\u9fa5]+\\]";
    // @的规则
    NSString *atPattern = @"@[0-9a-zA-Z\\u4e00-\\u9fa5-_]+";
    // #话题#的规则
    NSString *topicPattern = @"#[0-9a-zA-Z\\u4e00-\\u9fa5]+#";
    // url链接的规则
    NSString *urlPattern = @"\\b(([\\w-]+://?|www[.])[^\\s()<>]+(?:\\([\\w\\d]+\\)|([^[:punct:]\\s]|/)))";
    NSString *pattern = [NSString stringWithFormat:@"%@|%@|%@|%@", emotionPattern, atPattern, topicPattern, urlPattern];
    
    // 利用当前文本生成attributedText
    NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
    
    NSMutableArray *statusParts = [NSMutableArray array];
    
    // 遍历并截取所有特殊文本
    [text enumerateStringsMatchedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
        
        // 过滤掉长度为0的空字符串
        if ((*capturedStrings).length == 0) return;
        
        DJStatusPart *statusPart = [[DJStatusPart alloc] init];
        statusPart.text = *capturedStrings;
        statusPart.range = *capturedRanges;
        statusPart.isSpecial = YES;
        statusPart.isEmotion = [(*capturedStrings) hasPrefix:@"["] && [(*capturedStrings) hasSuffix:@"]"]; // 若当前文本块以[]打头和结尾,则认为是表情
        [statusParts addObject:statusPart];
        
    }];
    
    
    // 遍历并截取所有非特殊文本
    [text enumerateStringsSeparatedByRegex:pattern usingBlock:^(NSInteger captureCount, NSString *const __unsafe_unretained *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
        
        // 过滤掉长度为0的空字符串
        if ((*capturedStrings).length == 0) return;
        
        DJStatusPart *statusPart = [[DJStatusPart alloc] init];
        statusPart.text = *capturedStrings;
        statusPart.range = *capturedRanges;
        statusPart.isSpecial = NO;
        statusPart.isEmotion = NO;
        [statusParts addObject:statusPart];
        
    }];
    
    
    // 对添加完毕的statusParts数组进行排序
    [statusParts sortUsingComparator:^NSComparisonResult(DJStatusPart *  _Nonnull obj1, DJStatusPart *  _Nonnull obj2) {
        
        if (obj1.range.length > obj2.range.location) {
            return NSOrderedDescending; // 如果第一个文本块的位置坐标大于第二个,则为降序,否则为升序
        }
        return NSOrderedAscending;
    }];
    
    // 取出数组中的文本块进行拼接
    for (DJStatusPart *part in statusParts) {
     
        NSAttributedString *subString = nil;
        if (part.isSpecial) { // 判断是否是特殊文本(若是特殊文本,则进行特殊处理,超链接:变色,表情文本:更换成表情图片)
            if (part.isEmotion) { // 判断当前文本块是否是表情
                
                NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
                attachment.image = [UIImage imageNamed:@"EmotionIcons/default/d_aini"];
                attachment.bounds = CGRectMake(0, -4, 16, 16);
                subString = [NSAttributedString attributedStringWithAttachment:attachment];
                
            } else { // 超链接&昵称
                subString = [[NSAttributedString alloc] initWithString:part.text attributes:@{NSForegroundColorAttributeName : [UIColor blueColor]}];
            }
        } else { // 不做任何处理
            subString = [[NSAttributedString alloc] initWithString:part.text attributes:@{NSForegroundColorAttributeName : [UIColor redColor]}];
        }

        [attributedText appendAttributedString:subString];
    }
    return attributedText;
    
}

最终效果:

 

posted @ 2016-12-12 22:40  夜行过客  阅读(619)  评论(0编辑  收藏  举报