项目要求实现“翻译”的功能,融云 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 Extra_BackgroupView_CornerRadius 6.f
复制代码
@interface RCDTextMessageCell ()
复制代码
@property (strong, nonatomic) UILabel *extraLabel;
复制代码
@property (strong, nonatomic) UIView *extraBackgroundView;
复制代码
@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];
复制代码
CGSize extraSize = [RCDTextMessageCell getTextLabelSize:extra];
复制代码
CGFloat finalHeight = superSize.height + extraSize.height;
复制代码
return CGSizeMake(superSize.width, finalHeight);
复制代码
+ (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]}
复制代码
textRect.size.height = ceilf(textRect.size.height);
复制代码
textRect.size.width = ceilf(textRect.size.width);
复制代码
return CGSizeMake(textRect.size.width + 5, textRect.size.height + 5);
复制代码
- (void)setDataModel:(RCMessageModel *)model {
复制代码
[super setDataModel:model];
复制代码
NSString *extra = model.extra;
复制代码
[self.extraLabel removeFromSuperview];
复制代码
[self.extraBackgroundView removeFromSuperview];
复制代码
CGSize extraSize = [[self class] getTextLabelSize:extra];
复制代码
CGRect superFrame = self.bubbleBackgroundView.frame;
复制代码
CGRect extraBackgroundViewFrame = CGRectZero;
复制代码
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);
复制代码
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;
复制代码
在聊天页面类导入并绑定自定义 cell :
#import "RCDTextMessageCell.h"
复制代码
[self registerClass:[RCDTextMessageCell class] forMessageClass:[RCTextMessage class]];
复制代码
在聊天页面实现长按消息的“翻译”方法:
@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];
复制代码
实现“翻译”方法,并将翻译好的内容设置到数据源中:
代码仅供参考,翻译的方法还需要自己来实现,把最终翻译好的结果赋值给 self.longTouchModel.extra
这里必须要提的是 cellSize = CGSizeZero,否则刷新 UI 不会改变 cell 的高度
刷新 self.conversationMessageCollectionView
如果翻译的是最后一条消息,需要滚动到底部,否则翻译的内容会被遮挡
if (self.longTouchModel) {
复制代码
NSString *result = @"翻译后的结果。";
复制代码
RCTextMessage *txtMsg = (RCTextMessage *)self.longTouchModel.content;
复制代码
if ([txtMsg.content isEqualToString:@"How are you?"]) {
复制代码
} else if ([txtMsg.content isEqualToString:@"I’m fine."]) {
复制代码
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 就完了,希望这篇分享能帮助到大家。
评论