新浪微博客户端(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; }
最终效果: