// // YMMessageInfoModel.m // YUMI // // Created by YUMI on 2022/10/21. // #import "XPMessageInfoModel.h" #import "XPRoomMessageConstant.h" @implementation XPMessageInfoModel - (instancetype)init { if ([super init]) { self.contentLeftMargin = 12; self.contentRightMargin = 0; self.contentTopMargin = 10; self.contentBottomMargin = 10; self.cellBottomMargin = 6; self.isUpdateContentFrame = NO; self.isHiddenBubble = NO; } return self; } - (void)setContent:(NSAttributedString *)content { _content = content; CGSize size = [content boundingRectWithSize:CGSizeMake(kRoomMessageMaxWidth, 0) options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin context:nil].size; YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(size.width, CGFLOAT_MAX)]; container.maximumNumberOfRows = 0; container.truncationType = YYTextTruncationTypeEnd; self.textLayout = [YYTextLayout layoutWithContainer:container text:content]; CGSize textSize = self.textLayout.textBoundingRect.size; // CGFloat anotherHeight = [self heightForAttributedStringUsingTextKit:content maxWidth:kRoomMessageMaxWidth].height; if ([NSString isEmpty:self.bubbleImageUrl]) { self.rowHeight = ceil(textSize.height) + self.cellBottomMargin + self.contentTopMargin + 20; } else { self.rowHeight = ceil(textSize.height) + self.contentTopMargin + self.contentBottomMargin + self.cellBottomMargin + 20; } self.rowHeight += 10; // if ([self.cellKey isEqualToString:@"ChatMessage"]) { // NSLog(@" ----- 11 ----- %@ : %@", [NSValue valueWithCGSize:textSize], [NSValue valueWithCGSize:[self heightForAttributedStringUsingTextKit:content maxWidth:kRoomMessageMaxWidth]]); // } // self.rowHeight = [self heightForAttributedText:content // maxWidth:kRoomMessageMaxWidth]; // CGFloat width = isMSRTL() ? 10 : 0; ////// width = self.vipIcon.length > 0 ? width + 15 : width; // CGSize maxSize = CGSizeMake(kRoomMessageMaxWidth - self.contentLeftMargin - self.contentRightMargin - 12, MAXFLOAT); // YYTextContainer *container = [YYTextContainer containerWithSize:maxSize]; // container.maximumNumberOfRows = 0; // YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:self.content]; // CGFloat rowHeight = layout.textBoundingSize.height + self.contentTopMargin + self.contentBottomMargin + self.cellBottomMargin; // self.rowHeight = rowHeight + width ; } - (CGSize)heightForAttributedStringUsingTextKit:(NSAttributedString *)attributedString maxWidth:(CGFloat)maxWidth { NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString]; NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(maxWidth, CGFLOAT_MAX)]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [layoutManager addTextContainer:textContainer]; [textStorage addLayoutManager:layoutManager]; // 让布局管理器计算文本高度 [layoutManager glyphRangeForTextContainer:textContainer]; return [layoutManager usedRectForTextContainer:textContainer].size; } - (CGFloat)heightForAttributedText:(NSAttributedString *)attributedText maxWidth:(CGFloat)maxWidth { // 创建一个 YYTextContainer YYTextContainer *container = [YYTextContainer new]; container.size = CGSizeMake(maxWidth, CGFLOAT_MAX); // 设置宽度,支持无限高度 container.maximumNumberOfRows = 0; // 允许多行 // 遍历富文本,设置未加载图片的占位尺寸 // 确认是否 “@用户名” 会影响计算结果 NSInteger index = 0; NSMutableAttributedString *mutableAttributedText = [attributedText mutableCopy]; [mutableAttributedText enumerateAttribute:YYTextAttachmentAttributeName inRange:NSMakeRange(0, mutableAttributedText.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { if ([value isKindOfClass:[YYTextAttachment class]]) { // TODO: 把图片变为字符串来占位, 观察结果是第二行字符长度少于前缀图片,则会高度减少 YYTextAttachment *attachment = (YYTextAttachment *)value; NSLog(@" ---00--- : %@", attachment.content); if (attachment.content == nil) { attachment.content = [[UIView alloc] init]; // 占位内容 NSValue *v = [self.extraSizeArray xpSafeObjectAtIndex:index]; if (value) { UIView *placeholderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [v CGSizeValue].width, [v CGSizeValue].height)]; attachment.content = placeholderView; // 使用占位尺寸 } else { *stop = YES; } } } }]; // 通过 YYTextLayout 创建布局 YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:mutableAttributedText]; self.textWidth = ceil(layout.textBoundingSize.width); // 返回布局的文本高度 return ceil(layout.textBoundingSize.height) + self.contentTopMargin + self.contentBottomMargin + self.cellBottomMargin; // 向上取整,避免内容裁切 } @end