項目要求實現(xiàn)“翻譯”的功能,融云 SDK 本身沒這個功能飘蚯,所以只能曲線救國了析命,通過自定義消息來實現(xiàn),下面是功能實現(xiàn)相關(guān)內(nèi)容工育。
資源鏈接:
官網(wǎng):https://www.rongcloud.cn/
自定義消息文檔:https://docs.rongcloud.cn/v4/views/im/ui/guide/private/conversation/msgsend/ios.html#createcustom
實現(xiàn)思路
- 創(chuàng)建自定義 cell虾宇,與 SDK 內(nèi)置的文本消息進行綁定。因為他們內(nèi)置的文本消息 cell 不支持?jǐn)U展顯示翻譯的內(nèi)容如绸,所以需要使用自定義 cell嘱朽。
- 在聊天頁面將自定義 cell 與內(nèi)置的文本消息進行綁定。
- 重寫長按消息 cell 的方法怔接,判斷如果是文本消息燥翅,增加“翻譯”按鈕。
- 點擊“翻譯”按鈕蜕提,對文本內(nèi)容進行翻譯森书,并將翻譯好的內(nèi)容設(shè)置到數(shù)據(jù)源中。
- 刷新 UI,會觸發(fā)自定義 cell 中的回調(diào)方法凛膏,在回調(diào)方法中重新設(shè)置高度杨名,并添加 UI,對數(shù)據(jù)源中翻譯好的內(nèi)容進行展示猖毫。
代碼部分
-
創(chuàng)建自定義 cell 繼承于 RCTextMessageCell台谍,m 文件中代碼如下,具體效果可自行調(diào)整
#import "RCDTextMessageCell.h" #define RCDScreenWidth [UIScreen mainScreen].bounds.size.width #define Font_Size 16 #define Extra_BackgroupView_CornerRadius 6.f @interface RCDTextMessageCell () //翻譯內(nèi)容的 Label @property (strong, nonatomic) UILabel *extraLabel; //翻譯內(nèi)容的背景圖 @property (strong, nonatomic) UIView *extraBackgroundView; @end @implementation RCDTextMessageCell + (CGSize)sizeForMessageModel:(RCMessageModel *)model withCollectionViewWidth:(CGFloat)collectionViewWidth referenceExtraHeight:(CGFloat)extraHeight { //翻譯好的內(nèi)容 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; //為了防止復(fù)用問題的處理 [self.extraLabel removeFromSuperview]; [self.extraBackgroundView removeFromSuperview]; //如果有翻譯的內(nèi)容吁断,添加 UI趁蕊,進行展示 if (extra.length > 0) { CGSize extraSize = [[self class] getTextLabelSize:extra]; CGRect superFrame = self.bubbleBackgroundView.frame; CGRect extraBackgroundViewFrame = CGRectZero; //判斷消息方向,設(shè)置翻譯背景圖的 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
-
在聊天頁面類導(dǎo)入并綁定自定義 cell :
#import "RCDTextMessageCell.h" - (void)viewDidLoad { [super viewDidLoad]; [self registerClass:[RCDTextMessageCell class] forMessageClass:[RCTextMessage class]]; }
-
在聊天頁面實現(xiàn)長按消息的“翻譯”方法:
- 創(chuàng)建一個屬性用于暫存長按時候的 model仔役。
@property (strong, nonatomic) RCMessageModel *longTouchModel;
-
重寫長按消息 cell 的方法掷伙,判斷如果是文本消息,增加“翻譯”按鈕又兵,translate 是實現(xiàn)“翻譯”的方法任柜。
- (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; }
-
實現(xiàn)“翻譯”方法,并將翻譯好的內(nèi)容設(shè)置到數(shù)據(jù)源中:
- 代碼僅供參考沛厨,翻譯的方法還需要自己來實現(xiàn)宙地,把最終翻譯好的結(jié)果賦值給 self.longTouchModel.extra
- 這里必須要提的是 cellSize = CGSizeZero,否則刷新 UI 不會改變 cell 的高度
- 刷新 self.conversationMessageCollectionView
- 如果翻譯的是最后一條消息逆皮,需要滾動到底部宅粥,否則翻譯的內(nèi)容會被遮擋
- (void)translate { if (self.longTouchModel) { NSString *result = @"翻譯后的結(jié)果。"; 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 時,顯示翻譯的內(nèi)容辰企,自定義 cell 會回調(diào)設(shè)置 CGSize 的方法风纠,改變 cell 高度况鸣,同時也會回調(diào) setDataModel 方法牢贸,在這個方法中添加翻譯的內(nèi)容,具體可以參考自定義 cell 的 m 文件中代碼镐捧,這里就不重復(fù)貼代碼了潜索。
到此為止,該功能已經(jīng)算是搞定了懂酱,同樣這個思路和處理方法也適用于“語音轉(zhuǎn)文字”竹习,把翻譯功能換成語音轉(zhuǎn)文字,cell 繼承于 RCVoiceMessageCell 就完了列牺,希望這篇分享能幫助到大家整陌。