我的项目要求实现“翻译”的性能,融云 SDK 自身没这个性能,所以只能曲线救国了,通过自定义音讯来实现,上面是性能实现相干内容。
资源链接:
官网:https://www.rongcloud.cn/
自定义音讯文档:https://docs.rongcloud.cn/v4/…
实现思路
- 创立自定义 cell,与 SDK 内置的文本音讯进行绑定。因为他们内置的文本音讯 cell 不反对扩大显示翻译的内容,所以须要应用自定义 cell。
- 在聊天页面将自定义 cell 与内置的文本音讯进行绑定。
- 重写长按音讯 cell 的办法,判断如果是文本音讯,减少“翻译”按钮。
- 点击“翻译”按钮,对文本内容进行翻译,并将翻译好的内容设置到数据源中。
- 刷新 UI,会触发自定义 cell 中的回调办法,在回调办法中从新设置高度,并增加 UI,对数据源中翻译好的内容进行展现。
代码局部
-
创立自定义 cell 继承于 RCTextMessageCell,m 文件中代码如下,具体成果可自行调整
#import "RCDTextMessageCell.h" #define RCDScreenWidth [UIScreen mainScreen].bounds.size.width #define Font_Size 16 #define Extra_BackgroupView_CornerRadius 6.f @interface RCDTextMessageCell () // 翻译内容的 Label @property (strong, nonatomic) UILabel *extraLabel; // 翻译内容的背景图 @property (strong, nonatomic) UIView *extraBackgroundView; @end @implementation RCDTextMessageCell + (CGSize)sizeForMessageModel:(RCMessageModel *)model withCollectionViewWidth:(CGFloat)collectionViewWidth referenceExtraHeight:(CGFloat)extraHeight { // 翻译好的内容 NSString *extra = model.extra; CGSize superSize = [super sizeForMessageModel:model withCollectionViewWidth:collectionViewWidth referenceExtraHeight:extraHeight]; if (extra.length > 0) {CGSize extraSize = [RCDTextMessageCell getTextLabelSize:extra]; CGFloat finalHeight = superSize.height + extraSize.height; return CGSizeMake(superSize.width, finalHeight); }else {return superSize;
}
// 计算文本 size 的办法
-
(CGSize)getTextLabelSize:(NSString *)content {
if ([content length] > 0) { float maxWidth = RCDScreenWidth - (10 + [RCIM sharedRCIM].globalMessagePortraitSize.width + 10) * 2 - 5 - 35; CGRect textRect = [content boundingRectWithSize:CGSizeMake(maxWidth, 8000) options:(NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:Font_Size]} context:nil]; textRect.size.height = ceilf(textRect.size.height); textRect.size.width = ceilf(textRect.size.width); return CGSizeMake(textRect.size.width + 5, textRect.size.height + 5); } else {return CGSizeZero;}
}
-
(void)setDataModel:(RCMessageModel *)model {
[super setDataModel:model]; NSString *extra = model.extra; // 为了避免复用问题的解决 [self.extraLabel removeFromSuperview]; [self.extraBackgroundView removeFromSuperview]; // 如果有翻译的内容,增加 UI,进行展现 if (extra.length > 0) {CGSize extraSize = [[self class] getTextLabelSize:extra]; CGRect superFrame = self.bubbleBackgroundView.frame; CGRect extraBackgroundViewFrame = CGRectZero; // 判断音讯方向,设置翻译背景图的 frame if (model.messageDirection == MessageDirection_SEND) {extraBackgroundViewFrame = CGRectMake(superFrame.origin.x + superFrame.size.width - extraSize.width - 15, superFrame.size.height + 3, extraSize.width + 10, extraSize.height + 6); } else {extraBackgroundViewFrame = CGRectMake(superFrame.origin.x + 5, superFrame.origin.y + superFrame.size.height + 3, extraSize.width + 10, extraSize.height + 6); } self.extraBackgroundView = [[UIView alloc] initWithFrame:extraBackgroundViewFrame]; self.extraBackgroundView.backgroundColor = [UIColor whiteColor]; self.extraBackgroundView.layer.cornerRadius = Extra_BackgroupView_CornerRadius; [self.messageContentView addSubview:self.extraBackgroundView]; CGRect extraLabelFrame = CGRectMake(8, 3, extraSize.width, extraSize.height); self.extraLabel = [[UILabel alloc] initWithFrame:extraLabelFrame]; self.extraLabel.font = [UIFont systemFontOfSize:Font_Size]; self.extraLabel.numberOfLines = 0; [self.extraLabel setLineBreakMode:NSLineBreakByWordWrapping]; [self.extraLabel setTextAlignment:NSTextAlignmentLeft]; [self.extraBackgroundView addSubview:self.extraLabel]; self.extraLabel.text = extra; }
}
@end
2. 在聊天页面类导入并绑定自定义 cell :
#import “RCDTextMessageCell.h”
-
(void)viewDidLoad {
[super viewDidLoad]; [self registerClass:[RCDTextMessageCell class] forMessageClass:[RCTextMessage class]];
}
3. 在聊天页面实现长按音讯的“翻译”办法:
* 创立一个属性用于暂存长按时候的 model。
@property (strong, nonatomic) RCMessageModel *longTouchModel;
* 重写长按音讯 cell 的办法,判断如果是文本音讯,减少“翻译”按钮,translate 是实现“翻译”的办法。
- (NSArray<UIMenuItem *> *)getLongTouchMessageCellMenuList:(RCMessageModel *)model {NSMutableArray<UIMenuItem *> *menuList = [[super getLongTouchMessageCellMenuList:model] mutableCopy];
if ([model.content isKindOfClass:[RCTextMessage class]]) {UIMenuItem *forwardItem = [[UIMenuItem alloc] initWithTitle:@"翻译"
action:@selector(translate)];
self.longTouchModel = model;
[menuList addObject:forwardItem];
}
return menuList;
}
```
-
实现“翻译”办法,并将翻译好的内容设置到数据源中:
- 代码仅供参考,翻译的办法还须要本人来实现,把最终翻译好的后果赋值给 self.longTouchModel.extra
- 这里必须要提的是 cellSize = CGSizeZero,否则刷新 UI 不会扭转 cell 的高度
- 刷新 self.conversationMessageCollectionView
- 如果翻译的是最初一条音讯,须要滚动到底部,否则翻译的内容会被遮挡
- (void)translate {if (self.longTouchModel) { NSString *result = @"翻译后的后果。"; RCTextMessage *txtMsg = (RCTextMessage *)self.longTouchModel.content; if ([txtMsg.content isEqualToString:@"How are you?"]) {result = @"你好吗?";} else if ([txtMsg.content isEqualToString:@"I’m fine."]) {result = @"我很好。";} self.longTouchModel.extra = result; self.longTouchModel.cellSize = CGSizeZero; [self.conversationMessageCollectionView reloadData]; RCMessageModel *model = [self.conversationDataRepository lastObject]; if (model.messageId == self.longTouchModel.messageId) {[self scrollToBottomAnimated:YES]; } } }
- 刷新 UI 时,显示翻译的内容,自定义 cell 会回调设置 CGSize 的办法,扭转 cell 高度,同时也会回调 setDataModel 办法,在这个办法中增加翻译的内容,具体能够参考自定义 cell 的 m 文件中代码,这里就不反复贴代码了。
到此为止,该性能曾经算是搞定了,同样这个思路和解决办法也实用于“语音转文字”,把翻译性能换成语音转文字,cell 继承于 RCVoiceMessageCell 就完了,心愿这篇分享能帮忙到大家。