Compare commits
2 Commits
1bfc989fe9
...
cd9c2ea15a
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cd9c2ea15a | ||
![]() |
b9de95b4e6 |
@@ -2651,9 +2651,6 @@ BannerSchedulerDelegate
|
||||
- (XPRoomAnimationHitView *)bannerContainer {
|
||||
if (!_bannerContainer) {
|
||||
_bannerContainer = [[XPRoomAnimationHitView alloc] init];
|
||||
#if DEBUG
|
||||
_bannerContainer.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.4];
|
||||
#endif
|
||||
}
|
||||
return _bannerContainer;
|
||||
}
|
||||
@@ -3649,14 +3646,6 @@ BannerSchedulerDelegate
|
||||
self.savedTapPoint = CGPointZero;
|
||||
}
|
||||
|
||||
- (void)debugBannerSchedulerStatus {
|
||||
NSLog(@"🔍 BannerScheduler 调试信息:");
|
||||
NSLog(@"%@", [self.bannerScheduler debugStatus]);
|
||||
NSLog(@"🔍 RoomAnimationView 状态:");
|
||||
NSLog(@" - isRoomBannerV2Displaying: %@", self.isRoomBannerV2Displaying ? @"YES" : @"NO");
|
||||
NSLog(@" - bannerContainer.subviews.count: %ld", (long)self.bannerContainer.subviews.count);
|
||||
}
|
||||
|
||||
- (CGRect)calculateInteractiveBoundsForView:(UIView *)view {
|
||||
// 计算视图的可交互区域
|
||||
// 这里可以根据具体的 Banner 类型来调整可交互区域
|
||||
@@ -3674,44 +3663,6 @@ BannerSchedulerDelegate
|
||||
return bounds;
|
||||
}
|
||||
|
||||
- (void)testBannerScheduler {
|
||||
NSLog(@"🧪 开始测试 BannerScheduler");
|
||||
|
||||
// 测试添加 Banner
|
||||
AttachmentModel *testBanner = [[AttachmentModel alloc] init];
|
||||
testBanner.second = Custom_Message_Sub_Super_Gift_Banner;
|
||||
testBanner.data = @{@"test": @"data"};
|
||||
|
||||
[self.bannerScheduler enqueueBanner:testBanner];
|
||||
|
||||
NSLog(@"🧪 测试完成");
|
||||
}
|
||||
|
||||
- (void)debugTouchAreaCache {
|
||||
NSLog(@"🎯 触摸区域缓存调试信息:");
|
||||
TouchAreaCacheManager *cacheManager = [TouchAreaCacheManager sharedManager];
|
||||
[cacheManager debugPrintCache];
|
||||
}
|
||||
|
||||
- (void)debugGestureOptimizer {
|
||||
NSLog(@"🎯 手势优化器调试信息:");
|
||||
GestureOptimizer *optimizer = [GestureOptimizer sharedOptimizer];
|
||||
|
||||
// 测试不同区域的点
|
||||
CGFloat containerWidth = self.bannerContainer.bounds.size.width;
|
||||
CGPoint leftPoint = CGPointMake(containerWidth * 0.1, 40); // 左侧区域
|
||||
CGPoint centerPoint = CGPointMake(containerWidth * 0.5, 40); // 中央区域
|
||||
CGPoint rightPoint = CGPointMake(containerWidth * 0.9, 40); // 右侧区域
|
||||
|
||||
NSLog(@"🎯 测试左侧区域点:");
|
||||
[optimizer debugGestureAreaForPoint:leftPoint containerWidth:containerWidth];
|
||||
|
||||
NSLog(@"🎯 测试中央区域点:");
|
||||
[optimizer debugGestureAreaForPoint:centerPoint containerWidth:containerWidth];
|
||||
|
||||
NSLog(@"🎯 测试右侧区域点:");
|
||||
[optimizer debugGestureAreaForPoint:rightPoint containerWidth:containerWidth];
|
||||
}
|
||||
|
||||
#pragma mark - Cleanup Methods
|
||||
|
||||
|
@@ -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) {
|
||||
// 确保在设置attributedText之前先设置hasBubble属性
|
||||
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));
|
||||
}];
|
||||
}
|
||||
|
@@ -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];
|
||||
|
@@ -1928,19 +1928,19 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self handleNIMNotificationTypeMessage:message];
|
||||
} else if (message.messageType == NIMMessageTypeCustom) {
|
||||
// 自定义消息排查日志:first/second/size3
|
||||
#if DEBUG
|
||||
if ([message.messageObject isKindOfClass:[NIMCustomObject class]]) {
|
||||
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||
if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||
AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
||||
NSData *payloadJSON = nil;
|
||||
@try { payloadJSON = [NSJSONSerialization dataWithJSONObject:att.data ?: @{} options:0 error:nil]; } @catch (__unused NSException *e) {}
|
||||
NSLog(@"[Recv] 🎯 自定义消息 | first=%ld second=%ld | payload=%lub | sid=%@ | ts=%.3f",
|
||||
(long)att.first, (long)att.second, (unsigned long)payloadJSON.length,
|
||||
message.session.sessionId, [[NSDate date] timeIntervalSince1970]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//#if DEBUG
|
||||
// if ([message.messageObject isKindOfClass:[NIMCustomObject class]]) {
|
||||
// NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||
// if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||
// AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
||||
// NSData *payloadJSON = nil;
|
||||
// @try { payloadJSON = [NSJSONSerialization dataWithJSONObject:att.data ?: @{} options:0 error:nil]; } @catch (__unused NSException *e) {}
|
||||
// NSLog(@"[Recv] 🎯 自定义消息 | first=%ld second=%ld | payload=%lub | sid=%@ | ts=%.3f",
|
||||
// (long)att.first, (long)att.second, (unsigned long)payloadJSON.length,
|
||||
// message.session.sessionId, [[NSDate date] timeIntervalSince1970]);
|
||||
// }
|
||||
// }
|
||||
//#endif
|
||||
[self handleNimCustomTypeMessage:message];
|
||||
} else if(message.messageType == NIMMessageTypeText) {
|
||||
[self.messageContainerView handleNIMTextMessage:message];
|
||||
|
Reference in New Issue
Block a user