重构麦位相邻性判断逻辑,新增子类可重写的方法以支持自定义布局配置。更新各个麦位布局类,简化相邻性判断,确保布局逻辑的一致性和可维护性。同时,优化中点矩形计算方法,提升代码的可读性和性能。

This commit is contained in:
edwinQQQ
2025-09-15 19:09:48 +08:00
parent c8c9985db8
commit 345583c197
12 changed files with 172 additions and 249 deletions

View File

@@ -147,24 +147,15 @@
return point;
}
// PK01
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
// PK0-1
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return NO;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
if (!(left == 0 && right == 1)) return CGRectZero;
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
// 0-1
return (left == 0 && right == 1);
}
- (void)onRoomEntered {

View File

@@ -105,30 +105,15 @@
return point;
}
// (0) + 3(1-3)(1-2, 2-3)75x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
// 1-2, 2-3
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return NO;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
// 1-2, 2-3
if (!((left == 1 && right == 2) || (left == 2 && right == 3))) {
return CGRectZero;
}
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
return ((left == 1 && right == 2) || (left == 2 && right == 3));
}
- (void)onRoomEntered {

View File

@@ -157,26 +157,16 @@
return point;
}
// 2 dating 1-23-45-67-8
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
// 1-23-45-67-8
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return NO;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
BOOL valid = ((left == 1 && right == 2) || (left == 3 && right == 4) ||
// 1-23-45-67-8
return ((left == 1 && right == 2) || (left == 3 && right == 4) ||
(left == 5 && right == 6) || (left == 7 && right == 8));
if (!valid) return CGRectZero;
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
}
/**

View File

@@ -126,36 +126,9 @@
return point;
}
// 155x3175x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
//
BOOL sameRow = ((left >= 0 && left <= 4 && right >= 0 && right <= 4) ||
(left >= 5 && left <= 9 && right >= 5 && right <= 9) ||
(left >= 10 && left <= 14 && right >= 10 && right <= 14));
if (!sameRow) return CGRectZero;
// 1
NSInteger leftCol = (left <= 4) ? left : ((left <= 9) ? (left - 5) : (left - 10));
NSInteger rightCol = (right <= 4) ? right : ((right <= 9) ? (right - 5) : (right - 10));
if ((rightCol - leftCol) != 1) return CGRectZero;
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
// 155x3
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges {
return @[@[@0, @4], @[@5, @9], @[@10, @14]]; // 5
}
@end

View File

@@ -137,26 +137,13 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
return point;
}
// 线 index 1 75x75 scrollView
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
if (left < 0 || right >= [self countOfMicroView]) return CGRectZero;
if ((right - left) != 1) return CGRectZero; //
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
// scrollView 使
return CGRectMake(midX - size / 2.0, midTopY, size, size);
// 线线
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges {
NSInteger count = [self countOfMicroView];
if (count > 0) {
return @[@[@0, @(count - 1)]]; //
}
return @[];
}
- (void)didSelectAtIndex:(NSInteger)index {

View File

@@ -81,25 +81,13 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
return point;
}
// 线 index 1 75x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
if (left < 0 || right >= [self countOfMicroView]) return CGRectZero;
if ((right - left) != 1) return CGRectZero; //
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
// 线
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges {
NSInteger count = [self countOfMicroView];
if (count > 0) {
return @[@[@0, @(count - 1)]]; //
}
return @[];
}
- (void)didSelectAtIndex:(NSInteger)index {

View File

@@ -143,9 +143,10 @@ static const NSInteger kMicCountPerRow = 5;
return [self convertPoint:center toView:nil];
}
// 19175x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
// 19
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return NO;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
@@ -170,7 +171,7 @@ static const NSInteger kMicCountPerRow = 5;
else if (left >= 10 && left <= 13 && right >= 10 && right <= 13) {
// 11-12
if (left == 11 && right == 12) {
return CGRectZero;
return NO;
}
sameRow = YES;
leftCol = left - 10;
@@ -183,24 +184,10 @@ static const NSInteger kMicCountPerRow = 5;
rightCol = right - 14;
}
if (!sameRow) return CGRectZero;
if (!sameRow) return NO;
// 1
if ((rightCol - leftCol) != 1) return CGRectZero;
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
return (rightCol - leftCol) == 1;
}
@end

View File

@@ -128,37 +128,33 @@
return point;
}
// 75x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
// [1-4], [5-8]
if (firstIndex == secondIndex) {
return CGRectZero;
}
// [1-4][5-8]
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return NO;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
// [1-4], [5-8]
BOOL sameRowFirst = (left >= 1 && left <= 4 && right >= 1 && right <= 4);
BOOL sameRowSecond = (left >= 5 && left <= 8 && right >= 5 && right <= 8);
if (!(sameRowFirst || sameRowSecond)) {
return CGRectZero;
}
if (right - left != 1) {
return CGRectZero;
return NO;
}
// rect
CGRect leftRect = [self rectForViewAtIndex:left];
CGRect rightRect = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(leftRect) || CGRectIsEmpty(rightRect)) {
return CGRectZero;
}
return (right - left) == 1;
}
// mcWidth rect
// 使 (rect.origin.y + mcWidth/2 - 10)
// 使
- (CGRect)calculateMidpointRectBetweenLeft:(CGRect)leftRect andRight:(CGRect)rightRect {
//
CGFloat f_top = iPhoneXSeries ? firstRowTop : ownerHeight + marginV1 + ownerTopMargin_little_screen;
CGFloat s_top = iPhoneXSeries ? secondRowTop : mcHeight + marginV2 + f_top;
BOOL inFirstRow = sameRowFirst;
CGFloat circleCenterY = (inFirstRow ? (f_top + mcWidth / 2 - 10) : (s_top + mcWidth / 2 - 10));
// Y
BOOL inFirstRow = (CGRectGetMinY(leftRect) < s_top);
CGFloat circleCenterY = (inFirstRow ? (f_top + mcWidth / 2 - 10) : (s_top + mcWidth / 2 - 10)) - 10.0;
// X
CGFloat leftCenterX = CGRectGetMinX(leftRect) + mcWidth / 2;
@@ -167,8 +163,7 @@
// 75x75
CGFloat size = 75.0;
CGRect midRect = CGRectMake(midX - size / 2.0, circleCenterY - size / 2.0, size, size);
return midRect;
return CGRectMake(midX - size / 2.0, circleCenterY - size / 2.0, size, size);
}
@end

View File

@@ -77,6 +77,22 @@ NS_ASSUME_NONNULL_BEGIN
/// 计算两个横向相邻麦位中点的矩形(默认返回基于两个坑位中心点的 75x75非同一行或非相邻返回 CGRectZero
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex;
#pragma mark - 子类可重写的布局配置方法
/// 子类重写:返回麦位行配置,每行包含该行的索引范围数组
/// 例如:@[@[@0, @4], @[@5, @9]] 表示两行第一行0-4第二行5-9
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges;
/// 子类重写:是否允许同行相邻麦位显示中点矩形
- (BOOL)allowsAdjacentInSameRow;
/// 子类重写:自定义相邻性判断逻辑(默认使用行配置)
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex;
/// 子类重写自定义中点矩形计算默认使用顶部对齐的75x75
- (CGRect)calculateMidpointRectBetweenLeft:(CGRect)leftRect andRight:(CGRect)rightRect;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1215,35 +1215,84 @@
return CGRectZero;
}
/// rect 75x75
///
/// 使
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
// 1.
if (firstIndex == secondIndex) {
return CGRectZero;
}
// 2. 使
if (![self isAdjacentMicAtIndex:firstIndex andIndex:secondIndex]) {
return CGRectZero;
}
// 3.
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
CGRect leftRect = [self rectForViewAtIndex:left];
CGRect rightRect = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(leftRect) || CGRectIsEmpty(rightRect)) {
return CGRectZero;
}
// "行" y
CGFloat leftCenterY = CGRectGetMidY(leftRect);
CGFloat rightCenterY = CGRectGetMidY(rightRect);
if (fabs(leftCenterY - rightCenterY) > (CGRectGetHeight(leftRect) / 3.0)) {
return CGRectZero;
// 4. 使
return [self calculateMidpointRectBetweenLeft:leftRect andRight:rightRect];
}
#pragma mark -
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges {
//
NSInteger count = [self countOfMicroView];
if (count > 0) {
return @[@[@0, @(count - 1)]];
}
//
return @[];
}
- (BOOL)allowsAdjacentInSameRow {
return YES;
}
- (BOOL)isAdjacentMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return NO;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
// 使
NSArray<NSArray<NSNumber *> *> *rowRanges = [self micRowRanges];
for (NSArray<NSNumber *> *rowRange in rowRanges) {
if (rowRange.count >= 2) {
NSInteger rowStart = rowRange[0].integerValue;
NSInteger rowEnd = rowRange[1].integerValue;
//
if (left >= rowStart && left <= rowEnd && right >= rowStart && right <= rowEnd) {
// 1
return (right - left) == 1;
}
}
}
return NO;
}
- (CGRect)calculateMidpointRectBetweenLeft:(CGRect)leftRect andRight:(CGRect)rightRect {
// X
CGFloat leftCenterX = CGRectGetMidX(leftRect);
CGFloat rightCenterX = CGRectGetMidX(rightRect);
CGFloat midX = (leftCenterX + rightCenterX) / 2.0;
// 🔧 使
// 使10px
CGFloat leftTopY = CGRectGetMinY(leftRect);
CGFloat rightTopY = CGRectGetMinY(rightRect);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat midTopY = (leftTopY + rightTopY) / 2.0 - 10.0;
// 75x75
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
}

View File

@@ -94,35 +94,9 @@
return point;
}
// 105x2175x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
//
BOOL sameRow = ((left >= 0 && left <= 4 && right >= 0 && right <= 4) ||
(left >= 5 && left <= 9 && right >= 5 && right <= 9));
if (!sameRow) return CGRectZero;
// 1
NSInteger leftCol = (left <= 4) ? left : (left - 5);
NSInteger rightCol = (right <= 4) ? right : (right - 5);
if ((rightCol - leftCol) != 1) return CGRectZero;
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
// 105x2
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges {
return @[@[@0, @4], @[@5, @9]]; // 0-45-9
}
@end

View File

@@ -94,31 +94,19 @@ static const NSInteger kMicCountPerRow = 5;
return CGPointMake(x, y);
}
// 1 75x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
// 1
NSInteger leftRow = left / kMicCountPerRow;
NSInteger rightRow = right / kMicCountPerRow;
NSInteger leftCol = left % kMicCountPerRow;
NSInteger rightCol = right % kMicCountPerRow;
if (!(leftRow == rightRow && (rightCol - leftCol) == 1)) {
return CGRectZero;
// 205x4
- (NSArray<NSArray<NSNumber *> *> *)micRowRanges {
NSMutableArray *ranges = [NSMutableArray array];
NSInteger totalMics = [self countOfMicroView];
NSInteger rows = ceil((CGFloat)totalMics / kMicCountPerRow);
for (NSInteger i = 0; i < rows; i++) {
NSInteger start = i * kMicCountPerRow;
NSInteger end = MIN(start + kMicCountPerRow - 1, totalMics - 1);
[ranges addObject:@[@(start), @(end)]];
}
CGRect l = [self rectForViewAtIndex:left];
CGRect r = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(l) || CGRectIsEmpty(r)) return CGRectZero;
CGFloat midX = (CGRectGetMidX(l) + CGRectGetMidX(r)) / 2.0;
// 🔧 使
CGFloat leftTopY = CGRectGetMinY(l);
CGFloat rightTopY = CGRectGetMinY(r);
CGFloat midTopY = (leftTopY + rightTopY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midTopY, size, size);
return ranges;
}