新浪微博客户端(57)-显示微博文本中的表情
DJEmotionTool.h
#import <Foundation/Foundation.h> @class DJEmotion; @interface DJEmotionTool : NSObject /** 保存最近点击Emotion */ + (void)saveRecentEmotion:(DJEmotion *)emotion; /** 根据表情文件名获取对应的Emotion表情 */ + (DJEmotion *)emotionWithChs:(NSString *)chs; /** 获取存储在沙盒中最近点击的Emotion集合 */ + (NSArray *)recentEmotions; /** 获取默认表情 */ + (NSArray *)defaultEmotions; /** 获取Emoji表情 */ + (NSArray *)emojiEmotions; /** 获取浪小花表情 */ + (NSArray *)lxhEmotions; @end
DJEmotionTool.m
#import "DJEmotionTool.h" #import "DJEmotion.h" #import "MJExtension.h" // 最近表情保存路径 #define DJEmotionPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"emotion.archiver"] // 类似于java里面的静态成员变量 static NSMutableArray *_recentEmotions; @implementation DJEmotionTool static NSArray *_defaultEmotions, *_emojiEmotions, *_lxhEmotions; /** * 这个方法会在第一次使用这个类的时候调一次,且只调一次 * 类似于java中静态代码块 */ + (void)initialize { _recentEmotions = [NSKeyedUnarchiver unarchiveObjectWithFile:DJEmotionPath]; if (_recentEmotions == nil) { _recentEmotions = [NSMutableArray array]; } } /** 保存最近点击Emotion */ + (void)saveRecentEmotion:(DJEmotion *)emotion { // 移除之前存储的相同Emotion [_recentEmotions removeObject:emotion]; // 在数组的头部插入新的Emotion [_recentEmotions insertObject:emotion atIndex:0]; // 保存当前数组 [NSKeyedArchiver archiveRootObject:_recentEmotions toFile:DJEmotionPath]; } /** 根据表情文件名获取对应的Emotion表情 */ + (DJEmotion *)emotionWithChs:(NSString *)chs { /* 遍历当前表情数组,根据表情文字,获取对应的Emotion对象 */ NSArray *defaultEmotions = [self defaultEmotions]; for (DJEmotion *emotion in defaultEmotions) { if ([emotion.chs isEqualToString:chs]) { return emotion; } } NSArray *lxhEmotions = [self lxhEmotions]; for (DJEmotion *emotion in lxhEmotions) { if ([emotion.chs isEqualToString:chs]) { return emotion; } } return nil; } /** 获取存储在沙盒中最近点击的Emotion集合 */ + (NSArray *)recentEmotions { return _recentEmotions; } /** 获取默认表情 */ + (NSArray *)defaultEmotions { if (!_defaultEmotions) { NSString *path = [[NSBundle mainBundle] pathForResource:@"EmotionIcons/default/info.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 将字典数组转换成模型数组 _defaultEmotions = [DJEmotion mj_objectArrayWithKeyValuesArray:dictArray]; } return _defaultEmotions; } /** 获取Emoji表情 */ + (NSArray *)emojiEmotions { if (!_emojiEmotions) { NSString *path = [[NSBundle mainBundle] pathForResource:@"EmotionIcons/emoji/info.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 将字典数组转换成模型数组 _emojiEmotions = [DJEmotion mj_objectArrayWithKeyValuesArray:dictArray]; } return _emojiEmotions; } /** 获取浪小花表情 */ + (NSArray *)lxhEmotions { if (!_lxhEmotions) { NSString *path = [[NSBundle mainBundle] pathForResource:@"EmotionIcons/lxh/info.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 将字典数组转换成模型数组 _lxhEmotions = [DJEmotion mj_objectArrayWithKeyValuesArray:dictArray]; } return _lxhEmotions; } @end
#import "DJEmotionTool.h" #import "DJEmotion.h" #import "MJExtension.h" // 最近表情保存路径 #define DJEmotionPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"emotion.archiver"] // 类似于java里面的静态成员变量 static NSMutableArray *_recentEmotions; @implementation DJEmotionTool static NSArray *_defaultEmotions, *_emojiEmotions, *_lxhEmotions; /** * 这个方法会在第一次使用这个类的时候调一次,且只调一次 * 类似于java中静态代码块 */ + (void)initialize { _recentEmotions = [NSKeyedUnarchiver unarchiveObjectWithFile:DJEmotionPath]; if (_recentEmotions == nil) { _recentEmotions = [NSMutableArray array]; } } /** 保存最近点击Emotion */ + (void)saveRecentEmotion:(DJEmotion *)emotion { // 移除之前存储的相同Emotion [_recentEmotions removeObject:emotion]; // 在数组的头部插入新的Emotion [_recentEmotions insertObject:emotion atIndex:0]; // 保存当前数组 [NSKeyedArchiver archiveRootObject:_recentEmotions toFile:DJEmotionPath]; } /** 根据表情文件名获取对应的Emotion表情 */ + (DJEmotion *)emotionWithChs:(NSString *)chs { /* 遍历当前表情数组,根据表情文字,获取对应的Emotion对象 */ NSArray *defaultEmotions = [self defaultEmotions]; for (DJEmotion *emotion in defaultEmotions) { if ([emotion.chs isEqualToString:chs]) { return emotion; } } NSArray *lxhEmotions = [self lxhEmotions]; for (DJEmotion *emotion in lxhEmotions) { if ([emotion.chs isEqualToString:chs]) { return emotion; } } return nil; } /** 获取存储在沙盒中最近点击的Emotion集合 */ + (NSArray *)recentEmotions { return _recentEmotions; } /** 获取默认表情 */ + (NSArray *)defaultEmotions { if (!_defaultEmotions) { NSString *path = [[NSBundle mainBundle] pathForResource:@"EmotionIcons/default/info.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 将字典数组转换成模型数组 _defaultEmotions = [DJEmotion mj_objectArrayWithKeyValuesArray:dictArray]; } return _defaultEmotions; } /** 获取Emoji表情 */ + (NSArray *)emojiEmotions { if (!_emojiEmotions) { NSString *path = [[NSBundle mainBundle] pathForResource:@"EmotionIcons/emoji/info.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 将字典数组转换成模型数组 _emojiEmotions = [DJEmotion mj_objectArrayWithKeyValuesArray:dictArray]; } return _emojiEmotions; } /** 获取浪小花表情 */ + (NSArray *)lxhEmotions { if (!_lxhEmotions) { NSString *path = [[NSBundle mainBundle] pathForResource:@"EmotionIcons/lxh/info.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 将字典数组转换成模型数组 _lxhEmotions = [DJEmotion mj_objectArrayWithKeyValuesArray:dictArray]; } return _lxhEmotions; } @end
DJEmotionKeyboard.m
- (DJEmotionListView *)defaultEmotionView { if (!_defaultEmotionView) { DJEmotionListView *defaultEmotionView = [[DJEmotionListView alloc] init]; _defaultEmotionView = defaultEmotionView; defaultEmotionView.emotions = [DJEmotionTool defaultEmotions]; } return _defaultEmotionView; } - (DJEmotionListView *)emojiEmotionView { if (!_emojiEmotionView) { DJEmotionListView *emojiEmotionView = [[DJEmotionListView alloc] init]; _emojiEmotionView = emojiEmotionView; emojiEmotionView.emotions = [DJEmotionTool emojiEmotions]; } return _emojiEmotionView; } - (DJEmotionListView *)lxhEmotionView { if (!_lxhEmotionView) { DJEmotionListView *lxhEmotionView = [[DJEmotionListView alloc] init]; _lxhEmotionView = lxhEmotionView; lxhEmotionView.emotions = [DJEmotionTool lxhEmotions]; } return _lxhEmotionView; }
DJStatus.m
// 取出数组中的文本块进行拼接 for (DJStatusPart *part in statusParts) { NSAttributedString *subString = nil; if (part.isSpecial) { // 判断是否是特殊文本(若是特殊文本,则进行特殊处理,超链接:变色,表情文本:更换成表情图片) if (part.isEmotion) { // 判断当前文本块是否是表情 DJEmotion *emotion = [DJEmotionTool emotionWithChs:part.text]; if (emotion) { // 找到了当前文本对应的Emotion表情 NSString *emotionName = emotion.png; NSString *imageName = nil; if ([emotionName hasPrefix:@"d_"] || [emotionName hasPrefix:@"f_"] || [emotionName hasPrefix:@"h_"] || [emotionName hasPrefix:@"l_"] || [emotionName hasPrefix:@"o_"] || [emotionName hasPrefix:@"w_"]) { // 默认表情 imageName = [NSString stringWithFormat:@"EmotionIcons/default/%@",emotion.png]; } else if ([emotionName hasPrefix:@"lxh_"]) { // 浪小花表情 imageName = [NSString stringWithFormat:@"EmotionIcons/lxh/%@",emotion.png]; } NSTextAttachment *attachment = [[NSTextAttachment alloc] init]; attachment.image = [UIImage imageNamed:imageName]; attachment.bounds = CGRectMake(0, -4, 16, 16); subString = [NSAttributedString attributedStringWithAttachment:attachment]; } else { // 未在plist列表中找到对应表情,或该表情为Emoji subString = [[NSAttributedString alloc] initWithString:part.text]; } } else { // 超链接&昵称 subString = [[NSAttributedString alloc] initWithString:part.text attributes:@{NSForegroundColorAttributeName : [UIColor blueColor]}]; } } else { // 不做任何处理 subString = [[NSAttributedString alloc] initWithString:part.text]; } [attributedText appendAttributedString:subString];
最终效果:
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库