The project requires the realization of the function of “translation”. Rongyun SDK does not have this function, so it can only save the country by curve. It can be realized through custom messages.

Resource links:

Website: www.rongcloud.cn/ custom message document: docs. Rongcloud. Cn/v4 / views/im…

Implementation approach

  1. Create a custom cell and bind it to the built-in text message of the SDK. Because their built-in text message cell does not support extended display of translated content, a custom cell is required.
  2. Bind custom cells to built-in text messages in the chat page.
  3. Rewrite the method of long press message cell, judge if it is a text message, add “translate” button.
  4. Click the “Translate” button to translate the text content and set the translated content to the data source.
  5. When the UI is refreshed, the callback method in the custom cell is triggered. In the callback method, the height is reset and the UI is added to display the translated content in the data source.

Code section

  1. Create a custom cell inherited from RCTextMessageCell. The code in the M file is as follows. The specific effect can be adjusted by yourself

    #import "RCDTextMessageCell.h" #define RCDScreenWidth [UIScreen mainScreen].bounds.size.width #define Font_Size 16 #define Extra_BackgroupView_CornerRadius 6.f@interface RCDTextMessageCell () nonatomic) UILabel *extraLabel; @property (strong, nonatomic) UIView *extraBackgroundView; @end @implementation RCDTextMessageCell + (CGSize)sizeForMessageModel:(RCMessageModel *)model WithCollectionViewWidth :(CGFloat)collectionViewWidth referenceExtraHeight:(CGFloat)extraHeight {// translated content 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; + (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]; If (extra. Length > 0) {CGSize extraSize = [[self class] getTextLabelSize:extra]; CGRect superFrame = self.bubbleBackgroundView.frame; CGRect extraBackgroundViewFrame = CGRectZero; // Determine the direction of the message, Set 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; } } @endCopy the code
  2. Import and bind custom cell in chat page class:

    #import "RCDTextMessageCell.h"
    
    - (void)viewDidLoad {
        [super viewDidLoad];    
        [self registerClass:[RCDTextMessageCell class] forMessageClass:[RCTextMessage class]];
    }
    Copy the code
  3. Long press message “translate” method in chat page:

    • Create a property to hold the model for long pressing.
    @property (strong, nonatomic) RCMessageModel *longTouchModel;
    Copy the code
    • Override message cell long press method, determine if the message is text, add “translate” button, translate is the method to implement “translate”.

      - (NSArray<UIMenuItem *> *)getLongTouchMessageCellMenuList:(RCMessageModel *)model { NSMutableArray<UIMenuItem *> *menuList = [[super getLongTouchMessageCellMenuList:model] mutableCopy]; if ([model.content isKindOfClass:[RCTextMessage class]]) { UIMenuItem *forwardItem = [[UIMenuItem alloc] InitWithTitle :@" translate "action:@selector(translate)]; self.longTouchModel = model; [menuList addObject:forwardItem]; } return menuList; }Copy the code
  4. Implement the “translate” method and set the translated content to the data source:

    • Code for reference only, the method of translation also need oneself to realize, translate the final good results to the self. LongTouchModel. Extra
    • CellSize = CGSizeZero must be mentioned, otherwise refreshing the UI will not change the height of the cell
    • Refresh the self. ConversationMessageCollectionView
    • If the translation is the last message, scroll to the bottom, otherwise the translation will be blocked
    - (void)translate {if (self.longTouchModel) {NSString *result = @" translate result." ; RCTextMessage *txtMsg = (RCTextMessage *)self.longTouchModel.content; if ([txtMsg.content isEqualToString:@"How are you?"] ) {result = @" How are you?" ; } else if ([txtmsg.content isEqualToString:@"I'm fine."]) {result = @"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]; }}}Copy the code
  5. When the UI is refreshed, the translated content will be displayed. The custom cell will call back the method of setting CGSize and changing the height of the cell, and also call back the setDataModel method to add the translated content to this method. For details, please refer to the code in the M file of the custom cell. I won’t repeat the code here.

So far, this function has been done, the same idea and processing method is also applicable to “voice to text”, change the translation function into voice to text, cell inherited from RCVoiceMessageCell is finished, I hope this share can help you.