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

在实现“翻译”、“语音转文字”功能时,需要对 SDK 内置的消息 cell 做二次开发,即点击对应功能按钮时,需要增加 cell 的高度,并显示对应的内容。本知识库以“翻译”功能为例,“语音转文字”功能同理。
发布时间: 2019-08-13 16:34

回答:

实现思路:

  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

实现效果图




1.png

2.png

3.png

4.png