项目中的聊天功能需要发送和接收图片表情,查阅资料后决定使用富文本实现。思路如下:
客户端之间约定一个标识符并定义一个正则表达式;
-
将图片资源的名称与之保持一致,同时将资源文件导入到工程里,并新建一个plist文件便于取值;图片资源plist文件.png
收到文本消息时(本质上是一个文本消息),使用之前约定的正则表达式对消息内容进行匹配并筛选出满足条件的字符串;
使用富文本将字符串替换为图片并插入;
发送图片表情消息时,将图片表情进行转义,转换成字符串。
话不多说,上代码
@interface RPConvertToCommonEmoticonsHelper : NSObject
//使用单例进行初始化
+ (instancetype)shareInstancetype;
/*!
@method
@brief 表情编码转换为图片png表情
@param text 待转换的文字
@return 转换后的富文本
*/
- (NSAttributedString *)convertToPNGEmoticons:(NSString *)text;
/*!
@method
@brief 判断消息是否包含图片表情
@param text 待转换的文字
@return 是否包含
*/
- (BOOL)isPNGEmotion:(NSString *)text;
/*!
@method
@brief 图片png表情转换成字符串(发送消息的时候需要转换)
@param attributedString 待转换的富文本
@return 转换后的字符串
*/
- (NSMutableString *)convertAttributedText:(NSAttributedString *)attributedString;
@end
//自定义的文本附件
@interface RPAttachment : NSTextAttachment
@property (nonatomic , copy) NSString * text;
@end
#import "RPConvertToCommonEmoticonsHelper.h"
static RPConvertToCommonEmoticonsHelper * convertToCommonEmoticonsHelper = nil;
@implementation RPConvertToCommonEmoticonsHelper
+ (instancetype)shareInstancetype{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
convertToCommonEmoticonsHelper = [[self alloc] init];
});
return convertToCommonEmoticonsHelper;
}
- (NSAttributedString *)convertToPNGEmoticons:(NSString *)text{
if ([self isPNGEmotion:text]) {
RPLog(@"消息包含图片表情 == %@ ",text);
//表情标识的正则
NSString *regex = @"你的正则";
NSError *error;
NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:&error];
NSMutableAttributedString *string = [[ NSMutableAttributedString alloc ] initWithString:text attributes:nil ];
if (!error) {
// 对str字符串进行匹配
NSArray *matches = [regular matchesInString:text options:0 range:NSMakeRange(0, text.length)];
// 遍历匹配后的每一条记录
for (NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
NSRange range = [match range];
NSString *mStr = [text substringWithRange:range];
RPLog(@"%@", mStr);
//自定义的文本附件 继承NSTextAttachment 并添加一个String类型的属性 将来转义的时候要用到
RPAttachment *rpAttchImage = [[RPAttachment alloc] init];
rpAttchImage.text = mStr;
// 表情图片
rpAttchImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png",mStr]];
rpAttchImage.bounds = CGRectMake(x, y, width,height);
NSAttributedString *tempString = [NSAttributedString attributedStringWithAttachment:rpAttchImage];
if (rpAttchImage != nil) {
//插入表情
[string deleteCharactersInRange:range];
[string insertAttributedString:tempString atIndex:range.location];
}
}
}
//设置字体
[string addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(0, string.length)];
return string;
}else{
NSMutableAttributedString *string = [[ NSMutableAttributedString alloc ] initWithString:text attributes:nil ];
//设置字体
[string addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(0, string.length)];
return string;
}
}
- (BOOL)isPNGEmotion:(NSString *)text{
//根据表情标识 匹配表情
NSRegularExpression *numberRegular = [NSRegularExpression regularExpressionWithPattern:@"你的正则" options:NSRegularExpressionCaseInsensitive error:nil];
NSInteger count = [numberRegular numberOfMatchesInString:text options:NSMatchingReportProgress range:NSMakeRange(0, text.length)];
if (count > 0) {
return YES;
}else{
return NO;
}
}
- (NSMutableString *)convertAttributedText:(NSAttributedString *)attributedString{
//转义回来
NSMutableString *attStr = [[NSMutableString alloc] initWithString:attributedString.string];
[attributedString enumerateAttribute:NSAttachmentAttributeName
inRange:NSMakeRange(0, attributedString.length)
options:NSAttributedStringEnumerationReverse
usingBlock:^(id value, NSRange range, BOOL *stop){
if (value) {
//拿到文本附件
RPAttachment *attachment = (RPAttachment*)value;
NSString *str = [NSString stringWithFormat:@"%@",attachment.text];
//替换成图片表情的标识
[attStr replaceCharactersInRange:range withString:str];
}
}];
return attStr;
}
@end
@implementation RPAttachment
@end
效果如下
效果图.png