我的项目要求实现“翻译”的性能,融云 SDK 自身没这个性能,所以只能曲线救国了,通过自定义音讯来实现,上面是性能实现相干内容。
资源链接:
官网:https://www.rongcloud.cn/ 自定义音讯文档:https://docs.rongcloud.cn/v4/views/im/ui/guide/private/conversation/msgsend/ios.html#createcustom
实现思路
- 创立自定义 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 - (CGSize)sizeForMessageModel:(RCMessageModel *)model
-
在聊天页面类导入并绑定自定义 cell :
import “RCDTextMessageCell.h”
- (void)viewDidLoad {
[super viewDidLoad];
[self registerClass:[RCDTextMessageCell class] forMessageClass:[RCTextMessage class]];
}
- (void)viewDidLoad {
-
在聊天页面实现长按音讯的“翻译”办法:
- 创立一个属性用于暂存长按时候的 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;
}
- (NSArray<UIMenuItem *> )getLongTouchMessageCellMenuList:(RCMessageModel )model {
-
实现“翻译”办法,并将翻译好的内容设置到数据源中:
- 代码仅供参考,翻译的办法还须要本人来实现,把最终翻译好的后果赋值给 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 就完了,心愿这篇分享能帮忙到大家。