diff --git a/.vscode/settings.json b/.vscode/settings.json index 27479baa..7b56f0c8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "nonatomic" ], "cSpell.words": [ + "autoreleasepool", "Subview" ] } \ No newline at end of file diff --git a/YuMi/Modules/YMRoom/View/StageView/MicroView/MicroView.m b/YuMi/Modules/YMRoom/View/StageView/MicroView/MicroView.m index 061e8eef..1d352d2d 100644 --- a/YuMi/Modules/YMRoom/View/StageView/MicroView/MicroView.m +++ b/YuMi/Modules/YMRoom/View/StageView/MicroView/MicroView.m @@ -179,7 +179,8 @@ [self.faceImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.avatarImageView); - make.width.height.mas_equalTo(80); + make.width.mas_equalTo(kGetScaleWidth(80)); + make.height.mas_equalTo(80); }]; [self.groupTypeButton mas_makeConstraints:^(MASConstraintMaker *make) { @@ -210,6 +211,123 @@ } - (UIImage *)combineImageInOne:(RoomFaceSendInfoModel *)faceInfo { +#if DEBUG + NSAssert([NSThread isMainThread], @"UIKit操作必须在主线程执行!"); +#endif + // CGSize size = CGSizeMake(80, 80); + CGSize size = CGSizeMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds)); + UIImage *result; + NSInteger faceCount = faceInfo.resultIndexes.count > 9 ? 9 : faceInfo.resultIndexes.count; + CGFloat x = 0; + CGFloat y = 0; + CGFloat width = CGRectGetWidth(self.bounds); + CGFloat height = CGRectGetHeight(self.bounds); + CGFloat spaceX3 = 0; //三张图时的X间距 + CGFloat spaceX2 = (size.width - width * 2) / 2; //两张图时的X边距 + CGFloat spaceX1 = (size.width - width) / 2; //一张图时的X边距 + CGFloat spaceY3 = 0; //三张图时的Y间距 + CGFloat spaceY2 = (size.height - height * 2) / 2; //两张图时的Y间距 + CGFloat spaceY1 = (size.height - height) / 2; //一张图时的Y间距 + y = faceCount > 6 ? spaceY3 : (faceCount >= 3 ? spaceY2 : spaceY1); + x = faceCount % 3 == 0 && faceCount > 3 ? spaceX3 : (faceCount % 3 == 2 ? spaceX2 : spaceX1); + UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); + + // 根据显示类型处理不同布局 + RoomFaceInfoModel *faceModel = [[XPRoomFaceTool shareFaceTool] findFaceInfoById:faceInfo.faceId]; + +#if DEBUG +// faceModel.displayType = FaceDisplayType_OverLay; +#endif + + if (faceModel.displayType == FaceDisplayType_OnlyOne && faceCount > 0) { + UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); + // 只处理第一个元素并居中填满 + NSInteger index = [faceInfo.resultIndexes[0] integerValue]; + UIImage *singleImage = [[XPRoomFaceTool shareFaceTool] findFaceImageById:faceInfo.faceId index:index]; + if (!singleImage) singleImage = [UIImage imageNamed:@"default_face_placeholder"]; + + CGRect drawRect = [self aspectFitRectForImage:singleImage.size + inRect:CGRectMake(0, 0, size.width, size.height)]; + [singleImage drawInRect:drawRect]; + } else if (faceModel.displayType == FaceDisplayType_OverLay) { + size = CGSizeMake(size.width * 4, size.height*3); + UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); + // 横向叠加布局 + CGFloat currentX = 0; + for (int i = 0; i < faceCount; i++) { + if (i >= faceInfo.resultIndexes.count) break; + + @autoreleasepool { + NSInteger index = [faceInfo.resultIndexes[i] integerValue]; + UIImage *singleImage = [[XPRoomFaceTool shareFaceTool] findFaceImageById:faceInfo.faceId index:index]; + if (!singleImage) continue; + + CGRect drawRect = [self aspectFitRectForImage:singleImage.size + inRect:CGRectMake(currentX, + size.height/2 - singleImage.size.height/2, + singleImage.size.width, + singleImage.size.height)]; + [singleImage drawInRect:drawRect]; + currentX = CGRectGetMidX(drawRect); // 下一个图片从当前图片中心开始 + } + } + } else if (faceModel.displayType == FaceDisplayType_Flow) { + size = CGSizeMake(size.width * 3, size.height * 2); + UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); + // 动态行数计算和底部优先填充 + NSInteger maxPerRow = 3; + NSInteger totalRows = ceil((float)faceCount / (float)maxPerRow); + NSMutableArray *rowsDistribution = [NSMutableArray array]; + NSInteger remaining = faceCount; + + // 从底部行开始填充 + for (NSInteger row = totalRows-1; row >= 0; row--) { + NSInteger itemsInRow = (row == 0 && faceCount % maxPerRow != 0) ? faceCount % maxPerRow : maxPerRow; + itemsInRow = MIN(remaining, itemsInRow); + [rowsDistribution insertObject:@(itemsInRow) atIndex:0]; + remaining -= itemsInRow; + } + + // 计算布局起始位置 + CGFloat startY = size.height - totalRows * height; + __block NSInteger currentIndex = 0; + + // 按分配行数绘制 + [rowsDistribution enumerateObjectsUsingBlock:^(NSNumber *rowCount, NSUInteger rowIdx, BOOL * _Nonnull stop) { + NSInteger itemsInRow = [rowCount integerValue]; + CGFloat rowWidth = itemsInRow * width + (itemsInRow - 1) * spaceX3; + CGFloat startX = (size.width - rowWidth) / 2; + + for (NSInteger col = 0; col < itemsInRow; col++) { + if (currentIndex >= faceCount) return; + + NSInteger index = [faceInfo.resultIndexes[currentIndex] integerValue]; + UIImage *image = [[XPRoomFaceTool shareFaceTool] findFaceImageById:faceInfo.faceId index:index] ?: [UIImage imageNamed:@"default_face_placeholder"]; + + CGRect rect = CGRectMake(startX + col*(width+spaceX3), + startY + rowIdx*height, + width, + height); + [image drawInRect:[self aspectFitRectForImage:image.size inRect:rect]]; + currentIndex++; + } + }]; + } + result = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return result; +} + +// 新增尺寸计算方法 +- (CGRect)aspectFitRectForImage:(CGSize)imageSize inRect:(CGRect)container { + CGFloat scale = MIN(container.size.width/imageSize.width, container.size.height/imageSize.height); + return CGRectMake(container.origin.x + (container.size.width - imageSize.width*scale)/2, + container.origin.y + (container.size.height - imageSize.height*scale)/2, + imageSize.width*scale, + imageSize.height*scale); +} + +- (UIImage *)_combineImageInOne:(RoomFaceSendInfoModel *)faceInfo { CGSize size = CGSizeMake(80, 80); UIImage *result; NSInteger faceCount = faceInfo.resultIndexes.count > 9 ? 9 : faceInfo.resultIndexes.count; @@ -235,7 +353,7 @@ return singleImage; break; } - + if (faceModel.displayType == FaceDisplayType_Flow) { [singleImage drawInRect:CGRectMake(x, y, width, height)]; if (i % 3 == 0) { // 换行 @@ -757,6 +875,7 @@ _faceImageView = [[UIImageView alloc] init]; _faceImageView.backgroundColor = [UIColor clearColor]; _faceImageView.userInteractionEnabled = YES; + _faceImageView.contentMode = UIViewContentModeScaleAspectFit; } return _faceImageView; }