// // MOLiveMsgTextCell.m // MiMoLive // // Created by SuperC on 2025/6/9. // #import "MOLiveMsgTextCell.h" #import "UIView+MOCornerRadius.h" @interface MOLiveMsgTextCell () @property (nonatomic, strong) BigBtn *translateBtn;//翻译按钮 @end @implementation MOLiveMsgTextCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self != nil) { self.contentView.transform = CGAffineTransformMakeScale(1, -1); self.backgroundColor = [UIColor clearColor]; self.selectionStyle = UITableViewCellSelectionStyleNone; [self setupUI]; } return self; } - (void)setupUI{ [self.contentView addSubview:self.titleLab]; [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.contentView).offset(2.0); make.leading.trailing.equalTo(self.contentView); make.height.equalTo(@(MOTextTitleLabeHeight)); }]; [self.contentView addSubview:self.bgView]; [self.bgView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView).offset(MOBgViewOffSet); make.width.equalTo(@(MOBgViewMaxWidth)); make.top.equalTo(self.titleLab.mas_bottom).offset(MOBgViewOffSet); make.bottom.equalTo(self.contentView).offset(-MOBgViewOffSet); }]; [self.contentView addSubview:self.translateBtn]; CGFloat translateBtnWidth = [MOTools getWidthWithString:self.translateBtn.titleLabel.text font:[MOTextTools regularFont:10.0]] + 10 + 12.0 * 2.0 + 10.0; [self.translateBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.bgView.mas_right).offset(0); make.height.equalTo(@18.0); make.bottom.equalTo(self.bgView.mas_top).offset(-1); make.width.equalTo(@(translateBtnWidth)); }]; [self.contentView addSubview:self.bubbleImgView]; [self.bubbleImgView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.bgView).offset(-MOBgViewOffSet); make.right.equalTo(self.bgView).offset(MOBgViewOffSet); make.top.equalTo(self.bgView).offset(-MOBgViewOffSet); make.bottom.equalTo(self.bgView).offset(MOBgViewOffSet); }]; [self.contentView addSubview:self.contentTextView]; [self.contentTextView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.bgView).offset(MOContentLeftAndRighSpacing); make.right.equalTo(self.bgView).offset(-MOContentLeftAndRighSpacing); make.centerY.equalTo(self.bgView); make.height.equalTo(@16.0); }]; self.contentView.userInteractionEnabled = YES; _bubbleTapGestureRecognizer = [UITapGestureRecognizer new]; [_bubbleTapGestureRecognizer addTarget:self action:@selector(bubbleTapped:)]; _bubbleTapGestureRecognizer.delegate = self; [self.contentView addGestureRecognizer:self.bubbleTapGestureRecognizer]; _bubbleLongPressGestureRecognizer = [UILongPressGestureRecognizer new]; [_bubbleLongPressGestureRecognizer addTarget:self action:@selector(bubbleLongPressHandler:)]; [self.contentView addGestureRecognizer:self.bubbleLongPressGestureRecognizer]; } - (void)bubbleTapped:(UITapGestureRecognizer *)recognizer { MOLogV(@"触发了点击"); self.cellTapBlock ? self.cellTapBlock(self.cellModel) : nil; } - (void)bubbleLongPressHandler:(UILongPressGestureRecognizer *)recognizer{ if (recognizer.state == UIGestureRecognizerStateBegan){ MOLogV(@"触发了长按"); // self.cellLongPressBlock ? self.cellLongPressBlock(self.cellModel) : nil; // // recognizer.enabled = NO; //白名单用户 if(self.isWhiteList){ self.translateBtn.hidden = NO; } } // else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) // { // recognizer.enabled = YES; // } } - (void)setCellModel:(MORtmEntity *)cellModel{ _cellModel = cellModel; NSMutableAttributedString *titleAttri = [MOTextTools creteTitleTextWith:cellModel]; self.titleLab.attributedText = titleAttri; NSMutableAttributedString *contentAttri = [MOTextTools creteTextWith:cellModel]; self.contentTextView.attributedText = contentAttri; // 计算文本高度 CGFloat contentHeight = cellModel.cellHeight - MOTextTitleLabeHeight; if(contentHeight < MORtmContentMixHeight){ contentHeight = MORtmContentMixHeight; } [self.contentTextView mas_updateConstraints:^(MASConstraintMaker *make) { make.height.equalTo(@(contentHeight)); }]; self.bgView.backgroundColor = MONormalBgViewColor; MORtmJosnEntity *jsonEntity = (MORtmJosnEntity *)cellModel.data; MORtmUser *rtmUser = cellModel.user; NSInteger theBubble = rtmUser.bubble; if(theBubble == 0){ theBubble = rtmUser.dressing.bubble; } if(theBubble != 0){ //旧逻辑 - 本地找 UIImage *bubbleImg = [MOTextTools getBubbleImgWithCodeNum:theBubble]; if(bubbleImg){ [self.bubbleImgView setImage:bubbleImg]; self.bubbleImgView.hidden = NO; self.bgView.backgroundColor = [UIColor clearColor]; } else{ //使用新逻辑 - 素材库 MOEffect *bubbleObject = [[MOSvgaSourceManage shareManager] getPropsInfoWithCode:theBubble]; if(bubbleObject){ WEAKSELF NSURL *bubbleUrl = [NSURL URLWithString:bubbleObject.effectFile]; [[MOBubbleImageManager sharedManager] resizableImageWithURL:bubbleUrl completion:^(UIImage *image) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.bubbleImgView setImage:image]; }); }]; self.bubbleImgView.hidden = NO; self.bgView.backgroundColor = [UIColor clearColor]; } else{ self.bubbleImgView.hidden = YES; } } } else{ self.bubbleImgView.hidden = YES; } if(cellModel.cellHeight > (28.0 + MOTextTitleLabeHeight)){ [self.bgView mas_updateConstraints:^(MASConstraintMaker *make) { make.width.equalTo(@(MOBgViewMaxWidth)); }]; [self.translateBtn mas_updateConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.bgView.mas_right).offset(0); }]; } else{ CGFloat width = cellModel.contentWidth + MOContentLeftAndRighSpacing * 2.0 + MOContentOffSet * 2.0; if(width > MOBgViewMaxWidth){ width = MOBgViewMaxWidth; } if(width < MOBgViewMinWidth){ width = MOBgViewMinWidth; } [self.bgView mas_updateConstraints:^(MASConstraintMaker *make) { make.width.equalTo(@(width)); }]; CGFloat translateBtnWidth = [MOTools getWidthWithString:self.translateBtn.titleLabel.text font:[MOTextTools regularFont:10.0]] + 10 + 12.0 * 2.0 + 10.0; CGFloat translateRight = translateBtnWidth - width + 10.0; if(translateBtnWidth > width){ [self.translateBtn mas_updateConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.bgView.mas_right).offset(translateRight); }]; } } } - (void)layoutSubviews { [super layoutSubviews]; if(self.bubbleImgView.hidden){ [self.bgView setCornerRadiusWithTopLeft:4 topRight:12 bottomRight:12 bottomLeft:12]; } else{ [self.bgView setCornerRadiusWithTopLeft:0 topRight:0 bottomRight:0 bottomLeft:0]; } [self.translateBtn setCornerRadiusWithTopLeft:9.0 topRight:9.0 bottomRight:9.0 bottomLeft:2.0]; } - (void)awakeFromNib { [super awakeFromNib]; // Initialization code } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } #pragma mark - Lazy - (UIView *)bgView { if (_bgView == nil) { _bgView = [UIView new]; _bgView.backgroundColor = MONormalBgViewColor; } return _bgView; } - (UIImageView *)bubbleImgView{ if(!_bubbleImgView){ _bubbleImgView = [[UIImageView alloc] init]; [_bubbleImgView setImage:[UIImage imageNamed:@""]]; } return _bubbleImgView; } - (YYLabel *)titleLab{ if(!_titleLab){ _titleLab = [YYLabel new]; _titleLab.userInteractionEnabled = NO; _titleLab.textColor = [MOTools colorWithHexString:@"#FFFFFF" alpha:1.0]; } return _titleLab; } - (MOMsgContentTextView *)contentTextView{ if(!_contentTextView){ _contentTextView = [MOMsgContentTextView new]; _contentTextView.backgroundColor = [UIColor clearColor]; _contentTextView.textContainerInset = UIEdgeInsetsMake(MOContentBaseTopSpcing, MOContentBaseLeftSpacing, MOContentBaseBottomSpcing, MOContentBaseRightSpacing);//UITextView原本文字距离左右有间距,设置负数消除边距 _contentTextView.editable = NO; _contentTextView.scrollEnabled = NO;//防止滑出屏幕又滑入时有时单行文字消失 _contentTextView.userInteractionEnabled = NO; _contentTextView.textColor = [MOTools colorWithHexString:@"#FFFFFF" alpha:1.0]; } return _contentTextView; } - (BigBtn *)translateBtn{ if (!_translateBtn) { _translateBtn = [BigBtn buttonWithType:UIButtonTypeCustom]; [_translateBtn addTarget:self action:@selector(translateBtnClick) forControlEvents:UIControlEventTouchUpInside]; [_translateBtn setFont:[MOTextTools regularFont:10.0]]; [_translateBtn setTitle:NSLocalString(@"mimo_2_translate") forState:UIControlStateNormal]; [_translateBtn setTitle:NSLocalString(@"mimo_2_translate_load") forState:UIControlStateSelected]; [_translateBtn setTitleColor:[MOTools colorWithHexString:@"#4363FF"] forState:UIControlStateNormal]; [_translateBtn setTitleColor:kBaseTextColor_2 forState:UIControlStateSelected]; _translateBtn.backgroundColor = [UIColor whiteColor]; [_translateBtn setImage:[UIImage imageNamed:@"v_2_tranlate"] forState:UIControlStateNormal]; [_translateBtn setImage:[UIImage imageNamed:@"v_2_t_loading"] forState:UIControlStateSelected]; // 调整图文间距和内边距 CGFloat spacing = 5.0; // 减小图文间距 _translateBtn.contentEdgeInsets = UIEdgeInsetsMake(2, 12, 2, 12); // 增加左右内边距 _translateBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -spacing/2, 0, spacing/2); _translateBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing/2, 0, -spacing/2); // 2. 防止被压缩和截断 [_translateBtn setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [_translateBtn setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; _translateBtn.titleLabel.lineBreakMode = NSLineBreakByClipping; _translateBtn.titleLabel.adjustsFontSizeToFitWidth = NO; // 不自动缩小字体 _translateBtn.hidden = YES; } return _translateBtn; } - (void)translateBtnClick{ WEAKSELF NSString *bizIdStr = [MOTools generateUniqueID]; self.cellModel.bizId = bizIdStr; MORtmJosnEntity *jsonEntity = (MORtmJosnEntity *)self.cellModel.data; NSString *contentStr = jsonEntity.content; if(bizIdStr.length == 0){ return; } if(contentStr.length == 0){ return; } self.translateBtn.selected = YES; [self startSpinAnimationOnButton:self.translateBtn]; NSDictionary *dict = @{@"bizId":bizIdStr,@"content":contentStr}; [kHttpManager toTranslationTheContentWith:dict andBlock:^(id _Nonnull data, NSError * _Nonnull error) { [weakSelf stopSpinAnimationOnButton:weakSelf.translateBtn]; weakSelf.translateBtn.selected = NO; weakSelf.translateBtn.hidden = YES; if(kCode_Success){ MOLogV(@"%@",[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:data options:0 error:nil] encoding:NSUTF8StringEncoding]); NSDictionary *resultDict = data[@"data"]; NSString *bizIdStr = [MODataManager objectOrNilForKey:@"bizId" fromDictionary:resultDict]; NSString *contentStr = [MODataManager objectOrNilForKey:@"content" fromDictionary:resultDict]; if([weakSelf.cellModel.bizId isEqualToString:bizIdStr]){ MORtmJosnEntity *jsonEntityObject = (MORtmJosnEntity *)weakSelf.cellModel.data; if(contentStr.length != 0){ jsonEntityObject.content = contentStr; CGSize size = [MOTextTools textMessageCellSizeWith:weakSelf.cellModel]; weakSelf.cellModel.cellHeight = MAX(size.height + 1.0, MOTextLabelMinHeight); weakSelf.cellModel.contentWidth = [MOTextTools getWidthWith:weakSelf.cellModel]; } } weakSelf.toRefreshTheCell ? weakSelf.toRefreshTheCell(weakSelf.cellModel) : nil; } else{ MOLogV(@"toTranslationTheContentWith 接口报错了"); kShowNetError(data) } }]; } - (void)startSpinAnimationOnButton:(UIButton *)button { UIImageView *imageView = button.imageView; if (!imageView) return; // 创建旋转动画 CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; rotation.toValue = @(M_PI * 2); // 旋转360° rotation.duration = 1.0; // 动画时长(秒) rotation.repeatCount = HUGE_VALF; // 无限循环 rotation.removedOnCompletion = NO; rotation.fillMode = kCAFillModeForwards; [imageView.layer addAnimation:rotation forKey:@"spin"]; } - (void)stopSpinAnimationOnButton:(UIButton *)button { [button.imageView.layer removeAnimationForKey:@"spin"]; } @end