优化 XPRoomMessageContainerView 和 XPRoomMessageTableViewCell,改进消息处理逻辑,增加行高预计算方法,减少不必要的视图更新,提升性能和用户体验。同时,调整 UITableView 的约束更新方式,确保更高效的布局管理。

This commit is contained in:
edwinQQQ
2025-08-21 19:22:20 +08:00
parent b9de95b4e6
commit cd9c2ea15a
2 changed files with 74 additions and 30 deletions

View File

@@ -108,27 +108,16 @@
//
- (void)rebuildNormalConstraints {
[self.contentLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
[self.contentLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.contentView);
make.leading.mas_equalTo(self.contentView).offset(12);
make.bottom.mas_equalTo(self.contentView).offset(-20);
make.width.mas_equalTo(kRoomMessageMaxWidth);
}];
[self.bubbleImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
[self.bubbleImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.contentLabel).insets(UIEdgeInsetsMake(0, -10, 0, -10));
}];
// [self.bubbleImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
// make.leading.mas_equalTo(8);
// make.top.bottom.mas_equalTo(0);
// make.trailing.mas_equalTo(-8);
// }];
//
// [self.contentLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
// make.edges.mas_equalTo(UIEdgeInsetsMake(4, 12, 4, 12));
// }];
}
#pragma mark - tool
@@ -164,20 +153,28 @@
#pragma mark - Getters And Setters
- (void)setMessageInfo:(XPMessageInfoModel *)messageInfo {
if ([messageInfo.content isEqualToAttributedString:_messageInfo.content]) {
//
if (_messageInfo &&
[messageInfo.content isEqualToAttributedString:_messageInfo.content] &&
[messageInfo.bubbleImageUrl isEqualToString:_messageInfo.bubbleImageUrl] &&
[messageInfo.boomImageUrl isEqualToString:_messageInfo.boomImageUrl]) {
return;
}
_messageInfo = messageInfo;
if (messageInfo) {
// attributedTexthasBubble
self.contentLabel.hasBubble = ![NSString isEmpty:messageInfo.bubbleImageUrl];
BOOL hasBubble = ![NSString isEmpty:messageInfo.bubbleImageUrl];
if (self.contentLabel.hasBubble != hasBubble) {
self.contentLabel.hasBubble = hasBubble;
}
self.contentLabel.attributedText = messageInfo.content;
if (self.isLeftBigImage) {
if (self.isLeftBigImage && messageInfo.boomImageUrl) {
self.leftBigImageView.imageUrl = messageInfo.boomImageUrl;
}
}
}
- (void)updateLayoutWithoutBubble:(BOOL)hasBubble layoutSize:(CGSize)size {
@@ -216,12 +213,12 @@
UIImage *cutImage = [image1 cropRightAndBottomPixels:2];
self.bubbleImageView.image = [self resizableImage:cutImage];
}];
[self.bubbleImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
[self.bubbleImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.contentLabel).insets(UIEdgeInsetsMake(-10, -10, -10, -10));
}];
} else {
self.bubbleImageView.image = [UIImage imageWithColor:[DJDKMIMOMColor messageBubbleColor]];
[self.bubbleImageView mas_remakeConstraints:^(MASConstraintMaker *make) {
[self.bubbleImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.contentLabel).insets(UIEdgeInsetsMake(0, -10, 0, -10));
}];
}

View File

@@ -210,9 +210,11 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
}
// 4.
BOOL needReloadData = NO;
if (self.datasource.count > kRoomMessageMaxLength) {
NSInteger removedCount = kRoomMessageMaxLength / 2;
[self safelyRemoveMessages:removedCount];
needReloadData = YES; //
}
// 5.
@@ -230,7 +232,13 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
}
[self updateAllDataSource:tempNewDatas];
[self.incomingMessages removeAllObjects];
[self.messageTableView reloadData];
// 使 reloadData使
if (needReloadData) {
[self.messageTableView reloadData];
} else if (indexPaths.count > 0) {
[self.messageTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}
// 6.
[self scrollToFirstLocationOrBottom];
@@ -463,13 +471,16 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
return;
}
BOOL needReloadData = NO;
if (self.datasource.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.datasource objectsAtIndexes:set];
[self.datasource removeObjectsInArray:needRemoveMsgArray];
needReloadData = YES; //
}
NSMutableArray *tempArray = @[].mutableCopy;
NSMutableArray *indexPaths = @[].mutableCopy;
@kWeakify(self);
[self.incomingMessages enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
@kStrongify(self);
@@ -482,13 +493,20 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
if (model) {
[tempArray addObject:model];
[self.datasource addObject:model];
[indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]];
}
}];
[self.incomingMessages removeAllObjects];
[self updateAllDataSource:tempArray];
[self.messageTableView reloadData];
// 使 reloadData使
if (needReloadData) {
[self.messageTableView reloadData];
} else if (indexPaths.count > 0) {
[self.messageTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}
//
[self scrollToBottom:NO];
@@ -514,7 +532,17 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
}
if(source.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:source.count-1 inSection:0]; //
[self.messageTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:animated]; //
//
if (animated) {
// 使 dispatch_async
dispatch_async(dispatch_get_main_queue(), ^{
[self.messageTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:YES];
});
} else {
[self.messageTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
self.atCount = 0;
self.atTipBtn.hidden = YES;
[self.locationArray removeAllObjects];
@@ -1282,14 +1310,33 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
XPMessageInfoModel *model = [source xpSafeObjectAtIndex:indexPath.row];
// model 使 model
if (model.rowHeight > 0) {
return model.rowHeight + 20;
// 使 UITableViewAutomaticDimension
if (model.rowHeight <= 0) {
[self calculateRowHeightForModel:model];
}
// 使
// return 100;
return UITableViewAutomaticDimension;
return model.rowHeight + 20;
}
//
- (void)calculateRowHeightForModel:(XPMessageInfoModel *)model {
if (!model || !model.content) {
model.rowHeight = 44; //
return;
}
// 使 YYTextLayout
YYTextContainer *container = [YYTextContainer new];
container.size = CGSizeMake(kRoomMessageMaxWidth - 24, MAXFLOAT);
container.maximumNumberOfRows = 0;
YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:model.content];
model.rowHeight = layout.textBoundingSize.height;
//
if (model.rowHeight < 44) {
model.rowHeight = 44;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
@@ -1492,8 +1539,8 @@ NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
_messageTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_messageTableView.delegate = self;
_messageTableView.dataSource = self;
_messageTableView.rowHeight = UITableViewAutomaticDimension;
// _messageTableView.estimatedRowHeight = 44; //
// UITableViewAutomaticDimension使
_messageTableView.rowHeight = 64; //
_messageTableView.tableFooterView = [UIView new];
_messageTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_messageTableView.backgroundColor = [UIColor clearColor];