diff --git a/YuMi.xcodeproj/project.pbxproj b/YuMi.xcodeproj/project.pbxproj index 99e52251..fd745314 100644 --- a/YuMi.xcodeproj/project.pbxproj +++ b/YuMi.xcodeproj/project.pbxproj @@ -574,6 +574,7 @@ 4CD15D912D7E902800D9279F /* LoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD15D902D7E902800D9279F /* LoginViewController.m */; }; 4CD15D922D7EC2AC00D9279F /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23E56B3B2B03564B00C8DAC9 /* CoreTelephony.framework */; }; 4CD15D952D7FE9E400D9279F /* LoginTypesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD15D942D7FE9E400D9279F /* LoginTypesViewController.m */; }; + 4CD47BB52E61514900BCDA46 /* StageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD47BB42E61514900BCDA46 /* StageViewManager.m */; }; 4CD6FF662D673A5C00262AB7 /* AgentMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD6FF652D673A5C00262AB7 /* AgentMessageModel.m */; }; 4CD6FF692D673F7F00262AB7 /* AgentMessageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD6FF682D673F7F00262AB7 /* AgentMessageTableViewCell.m */; }; 4CE3A9462D22754C003F0796 /* RechargeUserModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3A9452D22754C003F0796 /* RechargeUserModel.m */; }; @@ -2809,6 +2810,8 @@ 4CD15D902D7E902800D9279F /* LoginViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginViewController.m; sourceTree = ""; }; 4CD15D932D7FE9E400D9279F /* LoginTypesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginTypesViewController.h; sourceTree = ""; }; 4CD15D942D7FE9E400D9279F /* LoginTypesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginTypesViewController.m; sourceTree = ""; }; + 4CD47BB32E61514900BCDA46 /* StageViewManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StageViewManager.h; sourceTree = ""; }; + 4CD47BB42E61514900BCDA46 /* StageViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StageViewManager.m; sourceTree = ""; }; 4CD6FF642D673A5C00262AB7 /* AgentMessageModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AgentMessageModel.h; sourceTree = ""; }; 4CD6FF652D673A5C00262AB7 /* AgentMessageModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AgentMessageModel.m; sourceTree = ""; }; 4CD6FF672D673F7F00262AB7 /* AgentMessageTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AgentMessageTableViewCell.h; sourceTree = ""; }; @@ -10793,6 +10796,8 @@ E8AEAED8271413530017FCE0 /* View */ = { isa = PBXGroup; children = ( + 4CD47BB32E61514900BCDA46 /* StageViewManager.h */, + 4CD47BB42E61514900BCDA46 /* StageViewManager.m */, 4CE746C92D929D500094E496 /* Common */, 4CB753CF2D30F08E00B13DF5 /* LuckyPackage */, 4CB753CE2D2FE80100B13DF5 /* RoomSideMenu */, @@ -12104,6 +12109,7 @@ E821077B2987D4AB00DE7040 /* MessageFindNewGreetModel.m in Sources */, 4C886BF22E015D61006F0BA7 /* MedalsModel.m in Sources */, E85E7BA32A4EC99300B6D00A /* XPMineGiveDiamondDetailsVC.m in Sources */, + 4CD47BB52E61514900BCDA46 /* StageViewManager.m in Sources */, 238A90072BA9729200828123 /* PIUniversalBannerView.m in Sources */, E8B846D826FDE17300A777FE /* XPMineRechargeProtocol.h in Sources */, E88C72A6282921D60047FB2B /* XPRoomBackMusicPlayerView.m in Sources */, diff --git a/YuMi/Modules/YMRoom/View/StageViewManager.h b/YuMi/Modules/YMRoom/View/StageViewManager.h new file mode 100644 index 00000000..4f044c98 --- /dev/null +++ b/YuMi/Modules/YMRoom/View/StageViewManager.h @@ -0,0 +1,60 @@ +// +// StageViewManager.h +// YUMI +// +// Created by YUMI on 2024/12/19. +// + +#import +#import "RoomInfoModel.h" +#import "RoomHostDelegate.h" + +@class StageView; + + +// 使用 RoomInfoModel 中已有的 RoomType 定义 +// 避免重复定义,保持代码一致性 + +NS_ASSUME_NONNULL_BEGIN + +@interface StageViewManager : NSObject + +@property (nonatomic, strong, readonly) StageView *currentStageView; +@property (nonatomic, + assign, + readonly) RoomType currentRoomType; + +/** + 更新 stageView 到指定房间类型 + @param roomType 房间类型 + @param roomInfo 房间信息 + @param container 容器视图 + @param delegate stageView 的代理对象 + @return 是否更新成功 + */ +- (BOOL)updateStageViewForRoomType:(RoomType)roomType + roomInfo:(RoomInfoModel *)roomInfo + container:(UIView *)container + delegate:(id)delegate; + +/** + 通知 stageView 更新 + @param roomInfo 房间信息 + */ +- (void)notifyStageViewUpdate:(RoomInfoModel *)roomInfo; + +/** + 清理资源 + */ +- (void)cleanup; + +/** + 检查是否需要切换 stageView 类型 + @param newType 新的房间类型 + @return 是否需要切换 + */ +- (BOOL)shouldChangeStageViewType:(RoomType)newType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/YuMi/Modules/YMRoom/View/StageViewManager.m b/YuMi/Modules/YMRoom/View/StageViewManager.m new file mode 100644 index 00000000..97b78b81 --- /dev/null +++ b/YuMi/Modules/YMRoom/View/StageViewManager.m @@ -0,0 +1,145 @@ +// +// StageViewManager.m +// YUMI +// +// Created by YUMI on 2024/12/19. +// + +#import "StageViewManager.h" +#import "RoomInfoModel.h" +#import "SocialStageView.h" +#import "TenMicStageView.h" +#import "FifteenMicStageView.h" +#import "NineteenMicStageView.h" +#import "TwentyMicStageView.h" +#import "DatingStageView.h" +#import "AnchorStageView.h" +#import "AnchorPkStageView.h" +#import "LittleGameStageView.h" +#import "LittleGameScrollStageView.h" + + +@interface StageViewManager () + +@property (nonatomic, strong) StageView *currentStageView; +@property (nonatomic, assign) RoomType currentRoomType; +@property (nonatomic, weak) UIView *container; + +@end + +@implementation StageViewManager + +- (instancetype)init { + self = [super init]; + if (self) { + _currentRoomType = RoomType_Game; // RoomType_Game 默认值 + } + return self; +} + +- (BOOL)updateStageViewForRoomType:(RoomType)roomType + roomInfo:(id)roomInfo + container:(UIView *)container + delegate:(id)delegate { + + // 检查是否需要切换 stageView 类型 + if ([self shouldChangeStageViewType:roomType]) { + NSLog(@"🔄 StageViewManager: 切换 stageView 类型 | 从 %ld 到 %ld", + (long)self.currentRoomType, (long)roomType); + + // 清理旧的 stageView + [self cleanup]; + + // 创建新的 stageView + [self createStageViewForType:roomType withDelegate:delegate]; + self.currentRoomType = roomType; + self.container = container; + } + + // 确保 stageView 已添加到容器 +// if (self.currentStageView && !self.currentStageView.superview && container) { +// [container insertSubview:self.currentStageView atIndex:0]; +// NSLog(@"✅ StageViewManager: stageView 已添加到容器"); +// } + + // 返回是否成功创建了 stageView + return self.currentStageView != nil; +} + +- (void)notifyStageViewUpdate:(id)roomInfo { + if (self.currentStageView && [self.currentStageView respondsToSelector:@selector(onRoomUpdate)]) { + NSLog(@"🔄 StageViewManager: 通知 stageView 更新 | type=%ld", (long)self.currentRoomType); + [self.currentStageView onRoomUpdate]; + } +} + +- (void)cleanup { + if (self.currentStageView) { + [self.currentStageView removeFromSuperview]; + self.currentStageView = nil; + NSLog(@"🧹 StageViewManager: 清理 stageView"); + } +} + +- (BOOL)shouldChangeStageViewType:(RoomType)newType { + return self.currentRoomType != newType || !self.currentStageView; +} + +#pragma mark - Private Methods + +- (void)createStageViewForType:(NSInteger)roomType withDelegate:(id)delegate { + // 根据房间类型创建对应的 stageView + // 注意:所有 stageView 都需要 delegate 来正确初始化 + + switch (roomType) { + case RoomType_Anchor: { // RoomType_Anchor + // 检查是否为 PK 模式 + // 这里需要根据 roomInfo 来判断,暂时使用默认的 AnchorStageView + if ([delegate respondsToSelector:@selector(getRoomInfo)]) { + RoomInfoModel *roomInfo = [delegate getRoomInfo]; + if (roomInfo.roomModeType == RoomModeType_Open_AcrossRoomPK_mode) { + self.currentStageView = [[AnchorPKStageView alloc] initWithDelegate:delegate]; + } else { + self.currentStageView = [[AnchorStageView alloc] initWithDelegate:delegate]; + } + } else { + self.currentStageView = [[AnchorStageView alloc] initWithDelegate:delegate]; + } + break; + } + case RoomType_MiniGame: { // RoomType_MiniGame + self.currentStageView = [[LittleGameScrollStageView alloc] initWithDelegate:delegate]; + break; + } + case RoomType_20Mic: { // RoomType_20Mic + self.currentStageView = [[TwentyMicStageView alloc] initWithDelegate:delegate]; + break; + } + case RoomType_19Mic: { // RoomType_19Mic + self.currentStageView = [[NineteenMicStageView alloc] initWithDelegate:delegate]; + break; + } + case RoomType_15Mic: { // RoomType_15Mic + self.currentStageView = [[FifteenMicStageView alloc] initWithDelegate:delegate]; + break; + } + case RoomType_10Mic: { // RoomType_10Mic + self.currentStageView = [[TenMicStageView alloc] initWithDelegate:delegate]; + break; + } + case RoomType_Game: // RoomType_Game + default: { + self.currentStageView = [[SocialStageView alloc] initWithDelegate:delegate]; + break; + } + } + + if (self.currentStageView) { + NSLog(@"✅ StageViewManager: 创建 stageView 成功 | type=%ld | class=%@", + (long)roomType, NSStringFromClass([self.currentStageView class])); + } else { + NSLog(@"❌ StageViewManager: 创建 stageView 失败 | type=%ld", (long)roomType); + } +} + +@end diff --git a/YuMi/Modules/YMRoom/View/XPRoomViewController.m b/YuMi/Modules/YMRoom/View/XPRoomViewController.m index dfc9f37c..f4c79371 100644 --- a/YuMi/Modules/YMRoom/View/XPRoomViewController.m +++ b/YuMi/Modules/YMRoom/View/XPRoomViewController.m @@ -76,6 +76,7 @@ #import "LittleGameStageView.h" #import "LittleGameScrollStageView.h" #import "XPRoomLittleGameContainerView.h" +#import "StageViewManager.h" #import "PIRoomEnterRedPacketView.h" #import "XPIAPRechargeViewController.h" #import "XPCandyTreeInsufficientBalanceView.h" @@ -127,6 +128,7 @@ XPCandyTreeInsufficientBalanceViewDelegate> @property (nonatomic,strong) RoomHeaderView *roomHeaderView; ///坑位信息 @property (nonatomic,strong) StageView *stageView; +@property (nonatomic,strong) StageViewManager *stageViewManager; @property (nonatomic,strong) TenMicStageView *tenMicStageView; @property (nonatomic,strong) FifteenMicStageView *fifteenMicStageView; @property (nonatomic,strong) TwentyMicStageView *twentyMicStageView; @@ -375,6 +377,7 @@ XPCandyTreeInsufficientBalanceViewDelegate> [self handleGiftComboCallBack]; + [self setupStageViewManager]; } //- (void)test { @@ -893,15 +896,42 @@ XPCandyTreeInsufficientBalanceViewDelegate> } - (BOOL)updateStageView { - Class stageViewClass = [self stageViewClassForRoomInfo:self.roomInfo]; - if (stageViewClass) { //&& ![self.stageView isKindOfClass:stageViewClass]) { - [self.stageView removeFromSuperview]; - self.stageView = nil; - self.stageView = [[stageViewClass alloc] initWithDelegate:self]; - self.stageView.alpha = 0; - return YES; + NSLog(@"🔄 updateStageView: 开始更新 stageView,当前 alpha = %.2f", self.stageView.alpha); + + // 优先使用 StageViewManager 来管理 stageView + if (self.stageViewManager) { + NSLog(@"🔧 updateStageView: 使用 StageViewManager"); + BOOL success = [self.stageViewManager updateStageViewForRoomType:self.roomInfo.type + roomInfo:self.roomInfo + container:self.view + delegate:self]; + if (success) { + self.stageView = self.stageViewManager.currentStageView; + if (self.stageView) { + NSLog(@"🔧 updateStageView: StageViewManager 设置 alpha = 0 (之前 = %.2f)", self.stageView.alpha); + self.stageView.alpha = 0; + NSLog(@"✅ StageViewManager 成功更新 stageView: %@", NSStringFromClass([self.stageView class])); + return YES; + } + } + NSLog(@"⚠️ StageViewManager 更新失败,降级到原有逻辑"); } + + // 降级处理:原有逻辑 +// NSLog(@"🔧 updateStageView: 使用降级逻辑"); +// Class stageViewClass = [self stageViewClassForRoomInfo:self.roomInfo]; +// if (stageViewClass) { //&& ![self.stageView isKindOfClass:stageViewClass]) { +// NSLog(@"🔧 updateStageView: 创建新的 stageView: %@", NSStringFromClass(stageViewClass)); +// [self.stageView removeFromSuperview]; +// self.stageView = nil; +// self.stageView = [[stageViewClass alloc] initWithDelegate:self]; +// NSLog(@"🔧 updateStageView: 降级逻辑设置 alpha = 0 (之前 = %.2f)", self.stageView.alpha); +// self.stageView.alpha = 0; +// NSLog(@"✅ 降级逻辑成功更新 stageView: %@", NSStringFromClass([self.stageView class])); +// return YES; +// } + NSLog(@"❌ 所有 stageView 更新方法都失败了"); return NO; } @@ -938,17 +968,22 @@ XPCandyTreeInsufficientBalanceViewDelegate> } - (void)changeStageViewOnRoomUpdate { + NSLog(@"🔄 changeStageViewOnRoomUpdate: 开始更新 stageView"); if (![self updateStageView]) { + NSLog(@"❌ changeStageViewOnRoomUpdate: updateStageView 失败"); return; } + NSLog(@"✅ changeStageViewOnRoomUpdate: updateStageView 成功,当前 alpha = %.2f", self.stageView.alpha); + // 🔧 新增:发送房间类型变化通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"RoomTypeChanged" object:nil userInfo:@{@"roomType": @(self.roomInfo.type)}]; if (!self.stageView.superview) { + NSLog(@"🔧 changeStageViewOnRoomUpdate: 添加 stageView 到视图层级"); [self.view insertSubview:self.stageView belowSubview:self.roomHeaderView]; @@ -970,7 +1005,12 @@ XPCandyTreeInsufficientBalanceViewDelegate> } } + NSLog(@"🔧 changeStageViewOnRoomUpdate: 设置 stageView.alpha = 1 (之前 = %.2f)", self.stageView.alpha); self.stageView.alpha = 1; + NSLog(@"✅ changeStageViewOnRoomUpdate: stageView.alpha 已设置为 1"); + + // 调试:检查最终状态 + [self debugStageViewStatus]; [self addExitGameButton]; @@ -1450,11 +1490,15 @@ XPCandyTreeInsufficientBalanceViewDelegate> } - (void)handleRoomWithoutPasswordAfterInitRoom { + NSLog(@"🔄 handleRoomWithoutPasswordAfterInitRoom: 开始处理无密码房间"); + self.roomInfo.datingState = (self.roomInfo.roomModeType == RoomModeType_Open_Blind) ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; + NSLog(@"🔧 handleRoomWithoutPasswordAfterInitRoom: 调用 changeStageViewOnRoomUpdate"); [self changeStageViewOnRoomUpdate]; + NSLog(@"✅ handleRoomWithoutPasswordAfterInitRoom: changeStageViewOnRoomUpdate 完成"); [self.roomHeaderView onRoomEntered]; [self.sideMenu onRoomEntered]; @@ -2096,6 +2140,7 @@ XPCandyTreeInsufficientBalanceViewDelegate> //房间类型是否变更了(从个播->普通,个播->小游戏等) newRoomInfo.hadChangeRoomType = self.roomInfo.type != newRoomInfo.type; BOOL anchorToOther = newRoomInfo.type != RoomType_Anchor && self.roomInfo.type == RoomType_Anchor;//个播变其他房 + RoomType currentType = self.roomInfo.type; self.roomInfo = newRoomInfo; [self.backContainerView onRoomUpdate]; @@ -3279,4 +3324,31 @@ XPCandyTreeInsufficientBalanceViewDelegate> } } +// 新增:StageViewManager 懒加载 +- (StageViewManager *)stageViewManager { + if (!_stageViewManager) { + _stageViewManager = [[StageViewManager alloc] init]; + NSLog(@"✅ StageViewManager 懒加载初始化成功"); + } + return _stageViewManager; +} + +// 新增:设置 StageViewManager +- (void)setupStageViewManager { + // 触发懒加载 + [self stageViewManager]; + NSLog(@"✅ StageViewManager 设置完成"); +} + +// 调试方法:检查 stageView 状态 +- (void)debugStageViewStatus { + NSLog(@"🔍 DEBUG: stageView 状态检查"); + NSLog(@" - stageView: %@", self.stageView); + NSLog(@" - stageView.alpha: %.2f", self.stageView.alpha); + NSLog(@" - stageView.hidden: %@", self.stageView.hidden ? @"YES" : @"NO"); + NSLog(@" - stageView.superview: %@", self.stageView.superview); + NSLog(@" - stageView.frame: %@", NSStringFromCGRect(self.stageView.frame)); + NSLog(@" - stageView.class: %@", NSStringFromClass([self.stageView class])); +} + @end diff --git a/YuMi/Network/HttpRequestHelper.m b/YuMi/Network/HttpRequestHelper.m index 29764659..38918b51 100644 --- a/YuMi/Network/HttpRequestHelper.m +++ b/YuMi/Network/HttpRequestHelper.m @@ -94,7 +94,7 @@ editParam = [MSParamsDecode msDecodeParams:editParam]; params = [self configBaseParmars:editParam]; -#if DEBUG +#if 0 // 构建完整的 URL NSString *baseUrl = [HttpRequestHelper getHostUrl]; NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method]; @@ -118,7 +118,7 @@ @kWeakify(self); [manager GET:method parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject]; -#if DEBUG +#if 0 NSLog(@"%@ - \n%@\n", method, [baseModel toJSONString]); #else #endif @@ -338,7 +338,7 @@ constructingBodyWithBlock:^(id _Nonnull formData) { params = [MSParamsDecode msDecodeParams:[params mutableCopy] ]; params = [self configBaseParmars:params]; AFHTTPSessionManager *manager = [HttpRequestHelper requestManager]; -#if DEBUG +#if 0 // 构建完整的 URL NSString *baseUrl = [HttpRequestHelper getHostUrl]; NSString *fullUrl = [NSString stringWithFormat:@"%@/%@", baseUrl, method]; @@ -363,7 +363,7 @@ constructingBodyWithBlock:^(id _Nonnull formData) { @kWeakify(self); [manager DELETE:method parameters:params headers:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { BaseModel *baseModel = [BaseModel modelWithDictionary:responseObject]; -#if DEBUG +#if 0 NSLog(@"\n%@\n", [baseModel toJSONString]); #else #endif diff --git a/issues/stageview-refactor-todo.md b/issues/stageview-refactor-todo.md new file mode 100644 index 00000000..db5cb431 --- /dev/null +++ b/issues/stageview-refactor-todo.md @@ -0,0 +1,25 @@ +## 当前状态 + +### ✅ 第一步:创建 StageViewManager 类 +- [x] 创建 StageViewManager.h +- [x] 创建 StageViewManager.m +- [x] 实现基本的 stageView 管理逻辑 +- [x] 使用 RoomInfoModel 中的 RoomType 定义 + +### ✅ 第二步:在 XPRoomViewController.m 中集成 +- [x] 添加 StageViewManager 的导入 +- [x] 添加 StageViewManager 属性声明 +- [x] 在 viewDidLoad 中初始化 StageViewManager +- [x] 添加 setupStageViewManager 方法 + +### 🔄 第三步:重构现有的 stageView 更新逻辑 +- [ ] 找到所有 stageView 创建和更新的地方 +- [ ] 替换为使用 StageViewManager +- [ ] 移除重复的 stageView 更新代码 +- [ ] 测试确保功能正常 + +### ⏳ 第四步:测试和验证 +- [ ] 测试不同房间类型的切换 +- [ ] 验证 stageView 更新逻辑 +- [ ] 性能测试 +- [ ] 代码审查