实现“翻译”、“语音转文字”功能时,对于消息 cell 的处理

实现思路:

  1. 创建自定义 cell,与 SDK 内置的文本消息进行绑定。因为 SDK 内置的文本消息 cell 不支持扩展显示翻译的内容,所以需要使用自定义 cell。

  2. 在聊天页面将自定义 cell 与 SDK 内置的文本消息进行绑定。

  3. 重写长按消息 cell 的方法,判断如果是文本消息,增加“翻译”按钮。

  4. 点击“翻译”按钮,对文本内容进行翻译,并将翻译好的内容设置到对应的数据源中。

  5. 刷新 UI,会触发自定义 cell 中的回调方法,在回调方法中重新设置高度,并添加 UI,对数据源中翻译好的内容进行展示。

实现代码:

1. 已将自定义 cell 类传到附件中,下载后导入工程即可。自定义cell.zip

2. 在聊天页面类绑定 cell :

a. #import “RCDTextMessageCell.h”.

b. 将自定义 cell 与 SDK 内置的文本消息进行绑定,重写下面方法,在方法中实现绑定,RCDTextMessageCell 是自定义 cell 类

- (void)viewDidLoad {
    [super viewDidLoad];    
    [self registerClass:[RCDTextMessageCell class] forMessageClass:[RCTextMessage class]];
}

3. 在聊天页面实现长按消息的“翻译”方法:

a. 创建一个属性 @property (strong, nonatomic) RCMessageModel *longTouchModel;,用于暂存长按时候的 model。

b. 重写长按消息 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;
}

4. 实现“翻译”方法,并将翻译好的内容设置到对应的数据源中:

a. 事例代码仅供参考,翻译的方法自己来实现,把最终翻译好的结果赋值给 self.longTouchModel.extra。

b. 设置 cellSize = CGSizeZero,否则刷新 UI 不会改变 cell 的高度。

c. 刷新 self.conversationMessageCollectionView

d. 如果翻译的是最后一条消息,需要滚动到底部,否则翻译的内容会被遮挡。

- (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];
        }
    }
}

5. 刷新 UI,显示翻译内容:

a. 回调设置 CGSize 的方法,也就是改变 cell 高度。(具体实现代码,请参考附件中的代码)

+ (CGSize)sizeForMessageModel:(RCMessageModel *)model
          withCollectionViewWidth:(CGFloat)collectionViewWidth
             referenceExtraHeight:(CGFloat)extraHeight

b. 回调 setDataModel 方法,添加 UI 并显示翻译好的内容。

1)设置两个 UI 属性,用于展示翻译内容

//翻译内容的 Label

@property (strong, nonatomic) UILabel *extraLabel;

//翻译内容的背景图

@property (strong, nonatomic) UIView *extraBackgroundView;

2)在回调下面方法时,判断是否有翻译内容,如果有,创建 UI 并显示。(具体实现代码,请参考附件中的代码)

   - (void)setDataModel:(RCMessageModel *)model

实现效果图