新增 MicMidpointRectManager 类以管理麦位中点矩形的绘制和动画,优化各个 StageView 中的中点矩形处理逻辑。同时,更新相关 StageView 类以集成中点矩形管理器,提升代码可维护性和用户体验。新增 SVGA 动画支持,确保中点矩形的动态展示效果。

This commit is contained in:
edwinQQQ
2025-09-04 18:43:39 +08:00
parent 8d20a9e44f
commit 10d4abf5ee
32 changed files with 893 additions and 1 deletions

View File

@@ -562,6 +562,12 @@
4CA532C32D5F37DC00B8F59F /* LuckyPackageMessageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA532C22D5F37DC00B8F59F /* LuckyPackageMessageTableViewCell.m */; };
4CA5A3342D93D4AB00CE41D6 /* 大.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CA5A3332D93D4AB00CE41D6 /* 大.svga */; };
4CACCCE42D9A695000CCB135 /* brove_gift.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CACCCE32D9A695000CCB135 /* brove_gift.svga */; };
4CAE69C52E69922B00A9FC35 /* mic_cp_lv1.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CAE69C02E69922B00A9FC35 /* mic_cp_lv1.svga */; };
4CAE69C62E69922B00A9FC35 /* mic_cp_lv2.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CAE69C12E69922B00A9FC35 /* mic_cp_lv2.svga */; };
4CAE69C72E69922B00A9FC35 /* mic_cp_lv4.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CAE69C32E69922B00A9FC35 /* mic_cp_lv4.svga */; };
4CAE69C82E69922B00A9FC35 /* mic_cp_lv5.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CAE69C42E69922B00A9FC35 /* mic_cp_lv5.svga */; };
4CAE69C92E69922B00A9FC35 /* mic_cp_lv3.svga in Resources */ = {isa = PBXBuildFile; fileRef = 4CAE69C22E69922B00A9FC35 /* mic_cp_lv3.svga */; };
4CAE69CC2E69A2DB00A9FC35 /* MicMidpointRectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAE69CB2E69A2DB00A9FC35 /* MicMidpointRectManager.m */; };
4CAFEFF62DD2F21B00CD81DF /* CreateEventPickerContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFEFF52DD2F21B00CD81DF /* CreateEventPickerContainerView.m */; };
4CAFF00A2DD342A400CD81DF /* MessagePublicEventModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF0092DD342A400CD81DF /* MessagePublicEventModel.m */; };
4CAFF00D2DD343B200CD81DF /* PublicEventTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CAFF00C2DD343B200CD81DF /* PublicEventTableViewCell.m */; };
@@ -2791,6 +2797,13 @@
4CA532C22D5F37DC00B8F59F /* LuckyPackageMessageTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LuckyPackageMessageTableViewCell.m; sourceTree = "<group>"; };
4CA5A3332D93D4AB00CE41D6 /* 大.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "大.svga"; sourceTree = "<group>"; };
4CACCCE32D9A695000CCB135 /* brove_gift.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = brove_gift.svga; sourceTree = "<group>"; };
4CAE69C02E69922B00A9FC35 /* mic_cp_lv1.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = mic_cp_lv1.svga; sourceTree = "<group>"; };
4CAE69C12E69922B00A9FC35 /* mic_cp_lv2.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = mic_cp_lv2.svga; sourceTree = "<group>"; };
4CAE69C22E69922B00A9FC35 /* mic_cp_lv3.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = mic_cp_lv3.svga; sourceTree = "<group>"; };
4CAE69C32E69922B00A9FC35 /* mic_cp_lv4.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = mic_cp_lv4.svga; sourceTree = "<group>"; };
4CAE69C42E69922B00A9FC35 /* mic_cp_lv5.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = mic_cp_lv5.svga; sourceTree = "<group>"; };
4CAE69CA2E69A2DB00A9FC35 /* MicMidpointRectManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MicMidpointRectManager.h; sourceTree = "<group>"; };
4CAE69CB2E69A2DB00A9FC35 /* MicMidpointRectManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MicMidpointRectManager.m; sourceTree = "<group>"; };
4CAFEFF42DD2F21B00CD81DF /* CreateEventPickerContainerView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CreateEventPickerContainerView.h; sourceTree = "<group>"; };
4CAFEFF52DD2F21B00CD81DF /* CreateEventPickerContainerView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CreateEventPickerContainerView.m; sourceTree = "<group>"; };
4CAFF0082DD342A400CD81DF /* MessagePublicEventModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MessagePublicEventModel.h; sourceTree = "<group>"; };
@@ -7110,6 +7123,11 @@
54FFD37D2C9BD12600DE61E5 /* 3.svga */,
54FFD37E2C9BD12600DE61E5 /* 4.svga */,
54FFD37F2C9BD12600DE61E5 /* 5.svga */,
4CAE69C02E69922B00A9FC35 /* mic_cp_lv1.svga */,
4CAE69C12E69922B00A9FC35 /* mic_cp_lv2.svga */,
4CAE69C22E69922B00A9FC35 /* mic_cp_lv3.svga */,
4CAE69C32E69922B00A9FC35 /* mic_cp_lv4.svga */,
4CAE69C42E69922B00A9FC35 /* mic_cp_lv5.svga */,
);
path = cp;
sourceTree = "<group>";
@@ -10904,6 +10922,8 @@
E8AEAEEA27141ACC0017FCE0 /* StageView */ = {
isa = PBXGroup;
children = (
4CAE69CA2E69A2DB00A9FC35 /* MicMidpointRectManager.h */,
4CAE69CB2E69A2DB00A9FC35 /* MicMidpointRectManager.m */,
E874B88527215CFF003954B9 /* Model */,
E8680707271959090024F48F /* MicroView */,
181D7F192726CE2A00B7C059 /* StageView.h */,
@@ -11771,6 +11791,11 @@
E80EC82628ACD84000D133C5 /* emoji_10@2x.png in Resources */,
E80EC82C28ACD84000D133C5 /* emoji_59@2x.png in Resources */,
E80EC81A28ACD84000D133C5 /* emoji_161@2x.png in Resources */,
4CAE69C52E69922B00A9FC35 /* mic_cp_lv1.svga in Resources */,
4CAE69C62E69922B00A9FC35 /* mic_cp_lv2.svga in Resources */,
4CAE69C72E69922B00A9FC35 /* mic_cp_lv4.svga in Resources */,
4CAE69C82E69922B00A9FC35 /* mic_cp_lv5.svga in Resources */,
4CAE69C92E69922B00A9FC35 /* mic_cp_lv3.svga in Resources */,
E80EC85228ACD84000D133C5 /* emoji_114@2x.png in Resources */,
E80EC81F28ACD84000D133C5 /* emoji_45@2x.png in Resources */,
E80EC85A28ACD84000D133C5 /* emoji_14@2x.png in Resources */,
@@ -13233,6 +13258,7 @@
E878893F273A54F500BF1D57 /* XPGiftPresenter.m in Sources */,
1464C5F929A4D00000AF7C94 /* XPIAPRechargeHeaderView.m in Sources */,
E83645A82A40AF5400E0DBE4 /* NSBundle+Localizable.m in Sources */,
4CAE69CC2E69A2DB00A9FC35 /* MicMidpointRectManager.m in Sources */,
23E9EA7F2A839B2F00B792F2 /* MessageTreasureFairyModel.m in Sources */,
E8778AFB2989034200CF139B /* XPSessionSayHelloEmptyTableViewCell.m in Sources */,
238B37B02AC55A2C00BFC9D5 /* XPTreasureFairyStoreResultCell.m in Sources */,

View File

@@ -76,6 +76,7 @@
#import "XPRoomFunctionContainerView.h"
#import "XPRoomRankEntranceView.h"
#import "XPRoomAnchorRankEnterView.h"
#import "SocialStageView.h"
#import "MSRoomOnLineView.h"
#import "XPTurboModeConstants.h"
#import "../MoreView/Manager/TurboModeStateManager.h"
@@ -3874,6 +3875,57 @@ BannerSchedulerDelegate
self.savedTapPoint = CGPointZero;
}
/// 1-4 5-8 75x75
- (void)debug_drawMicMidpointRects {
//
NSArray<UIView *> *subviews = [self.topContainer.subviews copy];
for (UIView *view in subviews) {
if (view.tag == 56001) {
[view removeFromSuperview];
}
}
// 宿 SocialStageView
SocialStageView *stageView = nil;
for (UIView *obj in self.hostDelegate.getSuperView.subviews) {
if ([obj isKindOfClass:[SocialStageView class]]) {
stageView = (SocialStageView *)obj;
break;
}
}
if (!stageView) {
return;
}
//
NSArray<NSArray<NSNumber *> *> *pairs = @[
@[@1, @2], @[@2, @3], @[@3, @4],
@[@5, @6], @[@6, @7], @[@7, @8]
];
for (NSArray<NSNumber *> *pair in pairs) {
NSInteger left = pair.firstObject.integerValue;
NSInteger right = pair.lastObject.integerValue;
CGRect stageRect = [stageView rectForMidpointBetweenMicAtIndex:left andIndex:right];
if (CGRectIsEmpty(stageRect)) {
continue;
}
//
CGRect rectInSelf = [self convertRect:stageRect fromView:stageView];
UIView *overlay = [[UIView alloc] initWithFrame:rectInSelf];
overlay.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.25];
overlay.layer.borderColor = [UIColor.redColor colorWithAlphaComponent:0.6].CGColor;
overlay.layer.borderWidth = 1.0;
overlay.layer.cornerRadius = 8.0;
overlay.clipsToBounds = YES;
overlay.tag = 56001;
[self.topContainer addSubview:overlay];
}
}
- (CGRect)calculateInteractiveBoundsForView:(UIView *)view {
//
// Banner

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface AnchorPKStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
@end
NS_ASSUME_NONNULL_END

View File

@@ -6,6 +6,7 @@
//
#import "AnchorPKStageView.h"
#import "MicMidpointRectManager.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
@@ -60,6 +61,7 @@
@property (strong, nonatomic) SVGAParser *parser;
///
@property (nonatomic, strong) SVGAImageView *svgDisplayView;
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@@ -67,6 +69,9 @@
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
[self addSubview:self.svgDisplayView];
[self addSubview:self.ruleButton];
[self.svgDisplayView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -142,6 +147,21 @@
return point;
}
// PK01
- (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 == 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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
- (void)onRoomEntered {
[super onRoomEntered];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface AnchorStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
@end
NS_ASSUME_NONNULL_END

View File

@@ -13,6 +13,7 @@
#import "AccountInfoStorage.h"
#import "XNDJTDDLoadingTool.h"
#import "YUMIMacroUitls.h"
#import "MicMidpointRectManager.h"
#import "TTPopup.h"
#import "Api+Room.h"
///Model
@@ -39,8 +40,22 @@
//
#define marginW 50
@interface AnchorStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation AnchorStageView
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
}
return self;
}
- (NSInteger)countOfMicroView {
return 4;
}
@@ -90,6 +105,27 @@
return point;
}
// (0) + 3(1-3)(1-2, 2-3)75x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
- (void)onRoomEntered {
[super onRoomEntered];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface DatingStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
@end
NS_ASSUME_NONNULL_END

View File

@@ -6,6 +6,7 @@
//
#import "DatingStageView.h"
#import "MicMidpointRectManager.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
@@ -52,6 +53,7 @@
@interface DatingStageView()
///
@property (nonatomic,strong) MicroDatingProgressView *datingProgressView;
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@@ -59,6 +61,9 @@
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
[self addSubview:self.datingProgressView];
[self.datingProgressView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(datingWidth);
@@ -152,6 +157,23 @@
return point;
}
// 2 dating 1-23-45-67-8
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
BOOL valid = ((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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
/**
*
*/

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface FifteenMicStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
@end
NS_ASSUME_NONNULL_END

View File

@@ -7,6 +7,7 @@
#import "FifteenMicStageView.h"
#import "SocialMicroView.h"
#import "MicMidpointRectManager.h"
//
#define firstRowTopMargin 60
// 58 + 5
@@ -28,8 +29,22 @@
//#define marginV2 15
//
#define tRowTop (sRowTop + mcHeight + lineMargin)
@interface FifteenMicStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation FifteenMicStageView
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
}
return self;
}
- (NSInteger)countOfMicroView {
return 15;
}
@@ -111,4 +126,31 @@
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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
@end

View File

@@ -6,11 +6,20 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface LittleGameScrollStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
/// 添加中点矩形到滚动视图
- (void)addMidpointRect:(UIView *)rectView;
/// 移除所有中点矩形
- (void)removeAllMidpointRects;
@end
NS_ASSUME_NONNULL_END

View File

@@ -14,6 +14,7 @@
///View
#import "LittleGameMicroView.h"
#import "MicMidpointRectManager.h"
UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
@@ -27,6 +28,7 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
@interface LittleGameScrollStageView ()
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@@ -92,6 +94,8 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self.scrollView];
[self setupObserver];
[self setupMicroScrollView];
@@ -133,6 +137,23 @@ 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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
// scrollView 使
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
- (void)didSelectAtIndex:(NSInteger)index {
MicroQueueModel* micModel = [self findMicroInfoByUid:[AccountInfoStorage instance].getUid];
if (micModel && micModel.userInfo.uid > 0 && micModel.userInfo.gameStatus == LittleGamePlayStatus_Plying) {
@@ -157,10 +178,40 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
_scrollView.scrollEnabled = YES;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.clipsToBounds = NO;
_scrollView.delegate = self;
}
return _scrollView;
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// scrollView
// rectForMidpointBetweenMicAtIndex:andIndex: scrollView
}
#pragma mark -
- (void)addMidpointRect:(UIView *)rectView {
// 使
NSString *micPairText = @"";
for (UIView *subview in rectView.subviews) {
if ([subview isKindOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)subview;
micPairText = label.text ?: @"";
break;
}
}
[self.midpointRectManager addMidpointRectAtFrame:rectView.frame
micPairText:micPairText
autoPlaySVGA:YES];
}
- (void)removeAllMidpointRects {
[self.midpointRectManager removeAllMidpointRects];
}
#pragma mark -
//

View File

@@ -6,11 +6,20 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface LittleGameStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
/// 添加中点矩形到视图
- (void)addMidpointRect:(UIView *)rectView;
/// 移除所有中点矩形
- (void)removeAllMidpointRects;
@end
NS_ASSUME_NONNULL_END

View File

@@ -14,6 +14,7 @@
///View
#import "LittleGameMicroView.h"
#import "MicMidpointRectManager.h"
UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
@@ -26,6 +27,8 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
@interface LittleGameStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation LittleGameStageView
@@ -36,6 +39,9 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeViewState:) name:kRoomRoomLittleGameMiniStageNotificationKey object:nil];
}
return self;
@@ -75,6 +81,22 @@ 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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
- (void)didSelectAtIndex:(NSInteger)index {
MicroQueueModel* micModel = [self findMicroInfoByUid:[AccountInfoStorage instance].getUid];
if (micModel && micModel.userInfo.uid > 0 && micModel.userInfo.gameStatus == LittleGamePlayStatus_Plying) {
@@ -94,4 +116,26 @@ UIKIT_EXTERN NSString * const kRoomRoomLittleGameMiniStageNotificationKey;
self.hidden = [[dic objectForKey:@"isMini"] boolValue];
}
#pragma mark -
- (void)addMidpointRect:(UIView *)rectView {
// 使
NSString *micPairText = @"";
for (UIView *subview in rectView.subviews) {
if ([subview isKindOfClass:[UILabel class]]) {
UILabel *label = (UILabel *)subview;
micPairText = label.text ?: @"";
break;
}
}
[self.midpointRectManager addMidpointRectAtFrame:rectView.frame
micPairText:micPairText
autoPlaySVGA:YES];
}
- (void)removeAllMidpointRects {
[self.midpointRectManager removeAllMidpointRects];
}
@end

View File

@@ -0,0 +1,49 @@
//
// MicMidpointRectManager.h
// YuMi
//
// Created by AI Assistant on 2024/12/19.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class MicMidpointRectManager;
@protocol MicMidpointRectManagerDelegate <NSObject>
@optional
/// 中点矩形动画播放完成
- (void)midpointRectManager:(MicMidpointRectManager *)manager didFinishAnimationAtRect:(CGRect)rect;
@end
@interface MicMidpointRectManager : NSObject
@property (nonatomic, weak) id<MicMidpointRectManagerDelegate> delegate;
@property (nonatomic, weak) UIView *containerView;
/// 初始化方法
- (instancetype)initWithContainerView:(UIView *)containerView;
/// 添加中点矩形支持SVGA动画
- (void)addMidpointRectAtFrame:(CGRect)frame
micPairText:(NSString *)micPairText
autoPlaySVGA:(BOOL)autoPlaySVGA;
/// 移除所有中点矩形
- (void)removeAllMidpointRects;
/// 移除指定位置的中点矩形
- (void)removeMidpointRectAtFrame:(CGRect)frame;
/// 播放指定位置的SVGA动画
- (void)playSVGAAnimationAtFrame:(CGRect)frame;
/// 停止所有SVGA动画
- (void)stopAllSVGAAnimations;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,159 @@
//
// MicMidpointRectManager.m
// YuMi
//
// Created by AI Assistant on 2024/12/19.
//
#import "MicMidpointRectManager.h"
#import <SVGA.h>
@interface MicMidpointRectManager ()
@property (nonatomic, strong) NSMutableArray<UIView *> *midpointRects;
@property (nonatomic, strong) NSMutableDictionary<NSString *, SVGAImageView *> *svgaViews;
@property (nonatomic, strong) SVGAParser *svgaParser;
@end
@implementation MicMidpointRectManager
- (instancetype)initWithContainerView:(UIView *)containerView {
if (self = [super init]) {
_containerView = containerView;
_midpointRects = [NSMutableArray array];
_svgaViews = [NSMutableDictionary dictionary];
_svgaParser = [[SVGAParser alloc] init];
}
return self;
}
- (void)addMidpointRectAtFrame:(CGRect)frame
micPairText:(NSString *)micPairText
autoPlaySVGA:(BOOL)autoPlaySVGA {
//
UIView *rectView = [[UIView alloc] initWithFrame:frame];
rectView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
rectView.layer.borderColor = [UIColor blueColor].CGColor;
rectView.layer.borderWidth = 2.0;
rectView.layer.cornerRadius = 8.0;
rectView.userInteractionEnabled = NO;
rectView.tag = 56002;
//
UILabel *label = [[UILabel alloc] init];
label.text = micPairText;
label.textColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:12];
label.textAlignment = NSTextAlignmentCenter;
label.frame = rectView.bounds;
[rectView addSubview:label];
//
[self.containerView addSubview:rectView];
[self.midpointRects addObject:rectView];
// SVGA
if (autoPlaySVGA) {
[self playSVGAAnimationAtFrame:frame];
}
NSLog(@"🔧 添加中点矩形: %@, frame: %@", micPairText, NSStringFromCGRect(frame));
}
- (void)removeAllMidpointRects {
// SVGA
[self stopAllSVGAAnimations];
//
for (UIView *rectView in self.midpointRects) {
[rectView removeFromSuperview];
}
[self.midpointRects removeAllObjects];
NSLog(@"🔧 移除所有中点矩形");
}
- (void)removeMidpointRectAtFrame:(CGRect)frame {
// SVGA
NSString *frameKey = NSStringFromCGRect(frame);
SVGAImageView *svgaView = self.svgaViews[frameKey];
if (svgaView) {
[svgaView stopAnimation];
[svgaView removeFromSuperview];
[self.svgaViews removeObjectForKey:frameKey];
}
//
for (UIView *rectView in [self.midpointRects copy]) {
if (CGRectEqualToRect(rectView.frame, frame)) {
[rectView removeFromSuperview];
[self.midpointRects removeObject:rectView];
break;
}
}
NSLog(@"🔧 移除指定位置的中点矩形: %@", NSStringFromCGRect(frame));
}
- (void)playSVGAAnimationAtFrame:(CGRect)frame {
// SVGA
NSArray *svgaFiles = @[@"mic_cp_lv1", @"mic_cp_lv2", @"mic_cp_lv3", @"mic_cp_lv4", @"mic_cp_lv5"];
NSString *randomSVGA = svgaFiles[arc4random_uniform((uint32_t)svgaFiles.count)];
// SVGA
NSString *svgaPath = [[NSBundle mainBundle] pathForResource:randomSVGA ofType:@"svga"];
if (!svgaPath) {
NSLog(@"⚠️ 找不到SVGA文件: %@", randomSVGA);
return;
}
// SVGAImageView
SVGAImageView *svgaView = [[SVGAImageView alloc] initWithFrame:frame];
svgaView.contentMode = UIViewContentModeScaleAspectFit;
svgaView.userInteractionEnabled = NO;
svgaView.backgroundColor = [UIColor clearColor];
//
[self.containerView addSubview:svgaView];
// SVGA
NSString *frameKey = NSStringFromCGRect(frame);
self.svgaViews[frameKey] = svgaView;
// SVGA
[self.svgaParser parseWithURL:[NSURL fileURLWithPath:svgaPath]
completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
dispatch_async(dispatch_get_main_queue(), ^{
svgaView.videoItem = videoItem;
svgaView.loops = 0;
svgaView.clearsAfterStop = YES;
[svgaView startAnimation];
NSLog(@"🎬 开始播放SVGA动画: %@, frame: %@", randomSVGA, NSStringFromCGRect(frame));
});
} failureBlock:^(NSError * _Nonnull error) {
NSLog(@"❌ SVGA动画解析失败: %@, error: %@", randomSVGA, error.localizedDescription);
[svgaView removeFromSuperview];
[self.svgaViews removeObjectForKey:frameKey];
}];
}
- (void)stopAllSVGAAnimations {
for (SVGAImageView *svgaView in self.svgaViews.allValues) {
[svgaView stopAnimation];
[svgaView removeFromSuperview];
}
[self.svgaViews removeAllObjects];
NSLog(@"🔧 停止所有SVGA动画");
}
#pragma mark - Dealloc
- (void)dealloc {
[self removeAllMidpointRects];
}
@end

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface NineteenMicStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
@end
NS_ASSUME_NONNULL_END

View File

@@ -7,6 +7,7 @@
#import "NineteenMicStageView.h"
#import "SocialMicroView.h"
#import "MicMidpointRectManager.h"
//
#define firstRowTopMargin 60
@@ -32,8 +33,22 @@
static const NSInteger kMicCountPerRow = 5;
@interface NineteenMicStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation NineteenMicStageView
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
}
return self;
}
- (NSInteger)countOfMicroView {
return 19; //
}
@@ -128,4 +143,59 @@ static const NSInteger kMicCountPerRow = 5;
return [self convertPoint:center toView:nil];
}
// 19175x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) return CGRectZero;
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
//
BOOL sameRow = NO;
NSInteger leftCol = -1, rightCol = -1;
// 0-4 (5)
if (left >= 0 && left <= 4 && right >= 0 && right <= 4) {
sameRow = YES;
leftCol = left;
rightCol = right;
}
// 5-6, 8-9 (4Boss7)
else if (((left >= 5 && left <= 6) && (right >= 5 && right <= 6)) ||
((left >= 8 && left <= 9) && (right >= 8 && right <= 9))) {
sameRow = YES;
leftCol = (left <= 6) ? left - 5 : left - 6;
rightCol = (right <= 6) ? right - 5 : right - 6;
}
// 10-13 (4)11-12
else if (left >= 10 && left <= 13 && right >= 10 && right <= 13) {
// 11-12
if (left == 11 && right == 12) {
return CGRectZero;
}
sameRow = YES;
leftCol = left - 10;
rightCol = right - 10;
}
// 14-18 (5)
else if (left >= 14 && left <= 18 && right >= 14 && right <= 18) {
sameRow = YES;
leftCol = left - 14;
rightCol = right - 14;
}
if (!sameRow) return CGRectZero;
// 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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
@end

View File

@@ -6,11 +6,18 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface SocialStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
/// 返回两个横向相邻麦位中点位置的矩形区域75x75
/// 仅当两个索引同一行且相邻,并且位于 [1-4] 或 [5-8] 范围内时有效;否则返回 CGRectZero。
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex;
@end
NS_ASSUME_NONNULL_END

View File

@@ -11,6 +11,7 @@
#import "YUMIMacroUitls.h"
#import "RoomInfoModel.h"
#import "ClientConfig.h"
#import "MicMidpointRectManager.h"
//
#define ownerTopMargin 100
#define ownerTopMargin_little_screen 35
@@ -34,8 +35,22 @@
//
#define secondRowTop (firstRowTop + mcHeight + marginV2)
@interface SocialStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation SocialStageView
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
}
return self;
}
- (NSInteger)countOfMicroView {
return 9;
}
@@ -113,4 +128,47 @@
return point;
}
// 75x75
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
// [1-4], [5-8]
if (firstIndex == secondIndex) {
return CGRectZero;
}
NSInteger left = MIN(firstIndex, secondIndex);
NSInteger right = MAX(firstIndex, secondIndex);
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;
}
// rect
CGRect leftRect = [self rectForViewAtIndex:left];
CGRect rightRect = [self rectForViewAtIndex:right];
if (CGRectIsEmpty(leftRect) || CGRectIsEmpty(rightRect)) {
return CGRectZero;
}
// mcWidth rect
// 使 (rect.origin.y + mcWidth/2 - 10)
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));
// X
CGFloat leftCenterX = CGRectGetMinX(leftRect) + mcWidth / 2;
CGFloat rightCenterX = CGRectGetMinX(rightRect) + mcWidth / 2;
CGFloat midX = (leftCenterX + rightCenterX) / 2.0;
// 75x75
CGFloat size = 75.0;
CGRect midRect = CGRectMake(midX - size / 2.0, circleCenterY - size / 2.0, size, size);
return midRect;
}
@end

View File

@@ -74,6 +74,9 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate;
-(void)exitNIMRoom;
/// 计算两个横向相邻麦位中点的矩形(默认返回基于两个坑位中心点的 75x75非同一行或非相邻返回 CGRectZero
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1210,6 +1210,34 @@
return CGRectZero;
}
/// rect 75x75
///
- (CGRect)rectForMidpointBetweenMicAtIndex:(NSInteger)firstIndex andIndex:(NSInteger)secondIndex {
if (firstIndex == secondIndex) {
return CGRectZero;
}
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;
}
//
CGFloat leftCenterX = CGRectGetMidX(leftRect);
CGFloat rightCenterX = CGRectGetMidX(rightRect);
CGFloat midX = (leftCenterX + rightCenterX) / 2.0;
CGFloat midY = (leftCenterY + rightCenterY) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
#pragma mark - StageViewProtocol -
- (NSInteger)positionToIndex:(NSString*)position {
return position.intValue + 1;

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface TenMicStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
@end
NS_ASSUME_NONNULL_END

View File

@@ -7,6 +7,7 @@
#import "TenMicStageView.h"
#import "SocialMicroView.h"
#import "MicMidpointRectManager.h"
//
#define firstRowTopMargin 60
// 58 + 5
@@ -27,8 +28,22 @@
//
//#define marginV2 15
@interface TenMicStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation TenMicStageView
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
}
return self;
}
- (NSInteger)countOfMicroView {
return 10;
}
@@ -79,5 +94,30 @@
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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
@end

View File

@@ -6,11 +6,14 @@
//
#import "StageView.h"
#import "MicMidpointRectManager.h"
NS_ASSUME_NONNULL_BEGIN
@interface TwentyMicStageView : StageView
@property (nonatomic, strong, readonly) MicMidpointRectManager *midpointRectManager;
//- (instancetype)initWithRows:(NSInteger)rows columns:(NSInteger)columns;
@end

View File

@@ -7,6 +7,7 @@
#import "TwentyMicStageView.h"
#import "SocialMicroView.h"
#import "MicMidpointRectManager.h"
//
#define firstRowTopMargin 60
@@ -32,10 +33,20 @@
@interface TwentyMicStageView ()
@property (nonatomic, strong) MicMidpointRectManager *midpointRectManager;
@end
@implementation TwentyMicStageView
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
if (self = [super initWithDelegate:delegate]) {
//
_midpointRectManager = [[MicMidpointRectManager alloc] initWithContainerView:self];
}
return self;
}
static const NSInteger kMicCountPerRow = 5;
- (NSInteger)countOfMicroView {
@@ -83,5 +94,27 @@ 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;
}
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 midY = (CGRectGetMidY(l) + CGRectGetMidY(r)) / 2.0;
CGFloat size = 75.0;
return CGRectMake(midX - size / 2.0, midY - size / 2.0, size, size);
}
@end

View File

@@ -1027,6 +1027,9 @@ XPCandyTreeInsufficientBalanceViewDelegate>
//
[self debugStageViewStatus];
// 🔧 SocialStageView
[self drawSocialStageMidpointRects];
[self addExitGameButton];
self.quickMessageContainerView.hidden = YES;
@@ -3413,4 +3416,114 @@ XPCandyTreeInsufficientBalanceViewDelegate>
NSLog(@"🎮 卡顿检测模拟已触发,计数将增加");
}
/// StageView
- (void)drawSocialStageMidpointRects {
if (!self.stageView) {
NSLog(@"🔧 当前没有 stageView跳过中点矩形绘制");
return;
}
NSString *stageViewClass = NSStringFromClass([self.stageView class]);
NSLog(@"🔧 开始绘制 %@ 中点矩形", stageViewClass);
//
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
// 使
id manager = [self.stageView valueForKey:@"midpointRectManager"];
if ([manager respondsToSelector:@selector(removeAllMidpointRects)]) {
[manager removeAllMidpointRects];
}
} else {
//
NSArray<UIView *> *subviews = [self.stageView.subviews copy];
for (UIView *view in subviews) {
if (view.tag == 56002) {
[view removeFromSuperview];
}
}
}
// StageView
NSArray *validPairs = nil;
if ([self.stageView isKindOfClass:[SocialStageView class]]) {
validPairs = @[@[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8]];
} else if ([self.stageView isKindOfClass:[TenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9]];
} else if ([self.stageView isKindOfClass:[FifteenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14]];
} else if ([self.stageView isKindOfClass:[NineteenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@8, @9], @[@10, @11], @[@12, @13], @[@14, @15], @[@15, @16], @[@16, @17], @[@17, @18]];
} else if ([self.stageView isKindOfClass:[TwentyMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14], @[@15, @16], @[@16, @17], @[@17, @18], @[@18, @19]];
} else if ([self.stageView isKindOfClass:[AnchorStageView class]]) {
validPairs = @[@[@1, @2], @[@2, @3]];
} else if ([self.stageView isKindOfClass:[DatingStageView class]]) {
validPairs = @[@[@1, @2], @[@3, @4], @[@5, @6], @[@7, @8]];
} else if ([self.stageView isKindOfClass:[LittleGameStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@4, @5]];
} else if ([self.stageView isKindOfClass:[LittleGameScrollStageView class]]) {
//
NSInteger micCount = [self.stageView countOfMicroView];
NSMutableArray *pairs = [NSMutableArray array];
for (NSInteger i = 0; i < micCount - 1; i++) {
[pairs addObject:@[@(i), @(i + 1)]];
}
validPairs = pairs;
} else if ([self.stageView isKindOfClass:[AnchorPKStageView class]]) {
validPairs = @[@[@0, @1]];
} else {
NSLog(@"🔧 未支持的 StageView 类型: %@", stageViewClass);
return;
}
NSLog(@"🔧 开始绘制 %@ 中点矩形,共 %lu 对相邻麦位", stageViewClass, (unsigned long)validPairs.count);
for (NSArray *pair in validPairs) {
NSInteger firstIndex = [pair[0] integerValue];
NSInteger secondIndex = [pair[1] integerValue];
CGRect rect = [self.stageView rectForMidpointBetweenMicAtIndex:firstIndex andIndex:secondIndex];
if (!CGRectIsEmpty(rect)) {
UIView *debugView = [[UIView alloc] initWithFrame:rect];
debugView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
debugView.layer.borderColor = [UIColor blueColor].CGColor;
debugView.layer.borderWidth = 2.0;
debugView.layer.cornerRadius = 8.0;
debugView.tag = 56002;
debugView.userInteractionEnabled = NO;
//
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
label.textColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:12];
label.textAlignment = NSTextAlignmentCenter;
label.frame = debugView.bounds;
[debugView addSubview:label];
// StageView
if ([self.stageView isKindOfClass:[LittleGameScrollStageView class]]) {
[(LittleGameScrollStageView *)self.stageView addMidpointRect:debugView];
} else if ([self.stageView isKindOfClass:[LittleGameStageView class]]) {
[(LittleGameStageView *)self.stageView addMidpointRect:debugView];
} else if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
// 使
id manager = [self.stageView valueForKey:@"midpointRectManager"];
if ([manager respondsToSelector:@selector(addMidpointRectAtFrame:micPairText:autoPlaySVGA:)]) {
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
[manager addMidpointRectAtFrame:rect micPairText:micPairText autoPlaySVGA:YES];
}
} else {
[self.stageView addSubview:debugView];
}
NSLog(@"🔧 绘制中点矩形: %ld-%ld, rect: %@", (long)firstIndex, (long)secondIndex, NSStringFromCGRect(rect));
} else {
NSLog(@"🔧 跳过无效麦位对: %ld-%ld", (long)firstIndex, (long)secondIndex);
}
}
NSLog(@"🔧 %@ 中点矩形绘制完成", stageViewClass);
}
@end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.