新增 XPBlankRoomModel 和 XPBlankCollectionViewCell 类,支持布局切换功能。更新 XPHomePartyViewController 以处理布局模式切换,优化数据源处理逻辑,确保在两列和一列布局之间正确插入和移除占位模型。同时,更新 XPHomePagingViewController 以发送布局切换通知,提升用户体验和代码可维护性。

This commit is contained in:
edwinQQQ
2025-09-10 18:59:36 +08:00
parent 5646168553
commit 49fbfb89a5
10 changed files with 266 additions and 35 deletions

View File

@@ -595,6 +595,8 @@
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 */; };
4CD401472E7183A8003F5009 /* XPBlankCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD401462E7183A8003F5009 /* XPBlankCollectionViewCell.m */; };
4CD4014A2E718E36003F5009 /* XPBlankRoomModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD401492E718E36003F5009 /* XPBlankRoomModel.m */; };
4CD47BB52E61514900BCDA46 /* StageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD47BB42E61514900BCDA46 /* StageViewManager.m */; };
4CD47BBE2E619F1700BCDA46 /* XPRoomMoreMenuAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD47BBB2E619F1700BCDA46 /* XPRoomMoreMenuAction.m */; };
4CD47BBF2E619F1700BCDA46 /* XPRoomMoreMenuActionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CD47BBD2E619F1700BCDA46 /* XPRoomMoreMenuActionContext.m */; };
@@ -2857,6 +2859,10 @@
4CD15D902D7E902800D9279F /* LoginViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginViewController.m; sourceTree = "<group>"; };
4CD15D932D7FE9E400D9279F /* LoginTypesViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginTypesViewController.h; sourceTree = "<group>"; };
4CD15D942D7FE9E400D9279F /* LoginTypesViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginTypesViewController.m; sourceTree = "<group>"; };
4CD401452E7183A8003F5009 /* XPBlankCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPBlankCollectionViewCell.h; sourceTree = "<group>"; };
4CD401462E7183A8003F5009 /* XPBlankCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPBlankCollectionViewCell.m; sourceTree = "<group>"; };
4CD401482E718E36003F5009 /* XPBlankRoomModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPBlankRoomModel.h; sourceTree = "<group>"; };
4CD401492E718E36003F5009 /* XPBlankRoomModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPBlankRoomModel.m; sourceTree = "<group>"; };
4CD47BB32E61514900BCDA46 /* StageViewManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StageViewManager.h; sourceTree = "<group>"; };
4CD47BB42E61514900BCDA46 /* StageViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StageViewManager.m; sourceTree = "<group>"; };
4CD47BB62E619F0B00BCDA46 /* XPTurboModeAction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPTurboModeAction.h; sourceTree = "<group>"; };
@@ -10221,6 +10227,8 @@
E87E62542A3F55BE002F68C9 /* Model */ = {
isa = PBXGroup;
children = (
4CD401482E718E36003F5009 /* XPBlankRoomModel.h */,
4CD401492E718E36003F5009 /* XPBlankRoomModel.m */,
23FF42772AA6E19C0055733C /* HomeMenuSourceModel.h */,
23FF42782AA6E19C0055733C /* HomeMenuSourceModel.m */,
E87DF4F32A42CC49009C1185 /* HomeMenuInfoModel.h */,
@@ -10283,6 +10291,8 @@
E87E625F2A3F5669002F68C9 /* Cell */ = {
isa = PBXGroup;
children = (
4CD401452E7183A8003F5009 /* XPBlankCollectionViewCell.h */,
4CD401462E7183A8003F5009 /* XPBlankCollectionViewCell.m */,
23FF25662ABC3BC00064E904 /* XPHomeGameCell.h */,
23FF25672ABC3BC00064E904 /* XPHomeGameCell.m */,
E87E627D2A3F5D28002F68C9 /* XPNewHomePlayItemCollectionViewCell.h */,
@@ -12448,6 +12458,7 @@
189DD53426DE255300AB55B1 /* TabbarViewController.m in Sources */,
23C9DFC92B84917B00B51558 /* PIRoomActivityChoosePlayCell.m in Sources */,
9BA3B40B293DCDFD0071DF1C /* XPVersionUpdateModel.m in Sources */,
4CD4014A2E718E36003F5009 /* XPBlankRoomModel.m in Sources */,
4C7989EC2D19392E006AE07B /* EmptyDataView.m in Sources */,
23C9DFCF2B85E21E00B51558 /* PIGuildSingleRoomIncomeCell.m in Sources */,
18EE401A2754BA9F00A452BF /* NIMMessageMaker.m in Sources */,
@@ -13465,6 +13476,7 @@
E87E91522796A15500A7B3F2 /* MicroExtModel.m in Sources */,
E8788948273A55D000BF1D57 /* XPGiftBarView.m in Sources */,
237700D32BC7CC7C00D661F1 /* NSObject+MJExtension.m in Sources */,
4CD401472E7183A8003F5009 /* XPBlankCollectionViewCell.m in Sources */,
4C886BEE2E014B6C006F0BA7 /* Api+Medals.m in Sources */,
E8D4DE442940462C00EC788D /* XPGiftTwelveStarBroadcastView.m in Sources */,
540EC1D02C89925F00F3BF0D /* GiftComboView.m in Sources */,

View File

@@ -0,0 +1,16 @@
//
// XPBlankRoomModel.h
// YuMi
//
// Created by Linus on 2024/12/19.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface XPBlankRoomModel : NSObject
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,12 @@
//
// XPBlankRoomModel.m
// YuMi
//
// Created by Linus on 2024/12/19.
//
#import "XPBlankRoomModel.h"
@implementation XPBlankRoomModel
@end

View File

@@ -0,0 +1,16 @@
//
// XPBlankCollectionViewCell.h
// YuMi
//
// Created by Linus on 2024/12/19.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface XPBlankCollectionViewCell : UICollectionViewCell
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,20 @@
//
// XPBlankCollectionViewCell.m
// YuMi
//
// Created by Linus on 2024/12/19.
//
#import "XPBlankCollectionViewCell.h"
@implementation XPBlankCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.contentView.backgroundColor = [UIColor clearColor];
}
return self;
}
@end

View File

@@ -0,0 +1,16 @@
//
// XPBlankRoomModel.h
// YuMi
//
// Created by Linus on 2024/12/19.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface XPBlankRoomModel : NSObject
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,12 @@
//
// XPBlankRoomModel.m
// YuMi
//
// Created by Linus on 2024/12/19.
//
#import "XPBlankRoomModel.h"
@implementation XPBlankRoomModel
@end

View File

@@ -198,18 +198,7 @@
_avatarView.imageUrl = _roomInfo.avatar;
self.levelImageView.imageUrl = roomInfo.roomLevelIcon;
for (int i = 0; i < self.membersCount; i++) {
NetImageView *iconView = _iconViews[i];
if (i < _roomInfo.micUsers.count) {
iconView.hidden = NO;
//
[iconView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.height.mas_equalTo(kGetScaleWidth(20));
}];
} else {
iconView.hidden = YES;
}
}
[self updateMicUsersDisplay];
switch (roomInfo.homeRoomType) {
case 1:{
@@ -296,19 +285,29 @@
_rankImageView.image = nil;
}
for (int i = 0; i < self.membersCount; i++) {
NetImageView *iconView = [self.contentView viewWithTag:100 + i];
if(i < _roomInfo.micUsers.count){
iconView.hidden = NO;
HomePlayMicUserModel *playModel = _roomInfo.micUsers[i];
iconView.imageUrl = playModel.avatar;
}else{
iconView.hidden = YES;
}
}
[self updateMicUsersDisplay];
[self layoutIfNeeded];
}
#pragma mark - Private Methods
- (void)updateMicUsersDisplay {
for (int i = 0; i < self.membersCount; i++) {
NetImageView *iconView = _iconViews[i];
if (i < _roomInfo.micUsers.count) {
iconView.hidden = NO;
//
[iconView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.width.height.mas_equalTo(kGetScaleWidth(20));
}];
HomePlayMicUserModel *playModel = _roomInfo.micUsers[i];
iconView.imageUrl = playModel.avatar;
} else {
iconView.hidden = YES;
}
}
}
#pragma mark -
- (NetImageView *)avatarView{
if(!_avatarView){

View File

@@ -217,6 +217,8 @@
- (void)didTapLayoutButton {
self.layoutButton.selected = !self.layoutButton.isSelected;
//
[[NSNotificationCenter defaultCenter] postNotificationName:@"kHomeLayoutToggle" object:nil];
}
#pragma mark - UIPageViewController Delegate & DataSource

View File

@@ -18,6 +18,8 @@
///View
#import "XPNewHomePartyCollectionViewCell.h"
#import "XPGuildEmptyCollectionViewCell.h"
#import "XPBlankCollectionViewCell.h"
#import "XPBlankRoomModel.h"
#import "XPWeakTimer.h"
///P
#import "XPHomePresenter.h"
@@ -107,12 +109,18 @@
@property (nonatomic,assign) int page;
///
@property (nonatomic,assign) BOOL hasNoMoreData;
///YESNO
@property (nonatomic,assign) BOOL isTwoColumnLayout;
@end
@implementation XPHomePartyViewController
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (BOOL)isHiddenNavBar {
return YES;
}
@@ -125,6 +133,7 @@
[super viewDidLoad];
[self initSubViews];
[self initSubViewConstraints];
[self setupLayoutNotification];
}
- (void)starBeginHeaderRefresh {
@@ -137,6 +146,93 @@
[self.view addSubview:self.collectionView];
}
- (void)setupLayoutNotification {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleLayoutToggle)
name:@"kHomeLayoutToggle"
object:nil];
}
- (void)handleLayoutToggle {
self.isTwoColumnLayout = !self.isTwoColumnLayout;
[self processCurrentDataSourceForLayout];
[self.collectionView reloadData];
}
- (void)processCurrentDataSourceForLayout {
if (self.datasource.count == 0) return;
if (self.isTwoColumnLayout) {
// bannermodel
NSInteger nonBannerCount = 0;
for (id item in self.datasource) {
if (![item isKindOfClass:[NSArray class]] && ![item isKindOfClass:[XPBlankRoomModel class]]) {
nonBannerCount++;
}
}
// bannermodel
if (nonBannerCount % 2 != 0) {
// bannermodel
NSInteger insertIndex = -1;
for (NSInteger i = self.datasource.count - 1; i >= 0; i--) {
id item = self.datasource[i];
if (![item isKindOfClass:[NSArray class]] && ![item isKindOfClass:[XPBlankRoomModel class]]) {
insertIndex = i + 1;
break;
}
}
if (insertIndex >= 0) {
[self.datasource insertObject:[[XPBlankRoomModel alloc] init] atIndex:insertIndex];
} else {
[self.datasource addObject:[[XPBlankRoomModel alloc] init]];
}
}
} else {
// model
NSMutableArray *processedDataSource = [NSMutableArray array];
for (id item in self.datasource) {
if (![item isKindOfClass:[XPBlankRoomModel class]]) {
[processedDataSource addObject:item];
}
}
self.datasource = processedDataSource;
}
}
- (NSArray *)processDataSourceForLayout:(NSArray *)originalList {
if (originalList.count == 0) return originalList;
if (self.isTwoColumnLayout) {
// bannermodel
NSMutableArray *processedDataSource = [NSMutableArray arrayWithArray:originalList];
NSInteger nonBannerCount = 0;
for (id item in originalList) {
if (![item isKindOfClass:[NSArray class]]) {
nonBannerCount++;
}
}
// bannermodel
if (nonBannerCount % 2 != 0) {
[processedDataSource addObject:[[XPBlankRoomModel alloc] init]];
}
return processedDataSource;
} else {
// model
NSMutableArray *processedDataSource = [NSMutableArray array];
for (id item in originalList) {
if (![item isKindOfClass:[XPBlankRoomModel class]]) {
[processedDataSource addObject:item];
}
}
return processedDataSource;
}
}
- (void)initSubViewConstraints {
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
@@ -184,7 +280,15 @@
[cell setTitle:YMLocalizedString(@"XPGuildEmptyCollectionViewCell0")];
return cell;
}
id item = [self.datasource xpSafeObjectAtIndex:indexPath.row];
// model
if ([item isKindOfClass:[XPBlankRoomModel class]]) {
XPBlankCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([XPBlankCollectionViewCell class]) forIndexPath:indexPath];
return cell;
}
if ([item isKindOfClass:[NSArray class]]) {
HomePartyBannerCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([HomePartyBannerCell class])
forIndexPath:indexPath];
@@ -208,6 +312,7 @@
if(self.datasource.count == 0) {
return 1;
}
return self.datasource.count;
}
@@ -217,15 +322,32 @@
}
id item = [self.datasource xpSafeObjectAtIndex:indexPath.row];
if ([item isKindOfClass:[NSArray class]]) {
return CGSizeMake(kGetScaleWidth(345), kGetScaleWidth(105));
} else {
return CGSizeMake(kGetScaleWidth(345), kGetScaleWidth(92));
// model0
if ([item isKindOfClass:[XPBlankRoomModel class]]) {
return CGSizeMake(kGetScaleWidth(165), kGetScaleWidth(165));
}
// banner banner
BOOL isBanner = [item isKindOfClass:[NSArray class]];
if (isBanner) {
return CGSizeMake(kGetScaleWidth(345), kGetScaleWidth(105));
}
if (self.isTwoColumnLayout) {
CGFloat side = kGetScaleWidth(165);
return CGSizeMake(side, side);
}
return CGSizeMake(kGetScaleWidth(345), kGetScaleWidth(92));
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
id item = [self.datasource xpSafeObjectAtIndex:indexPath.row];
// model
if ([item isKindOfClass:[XPBlankRoomModel class]]) {
return;
}
if ([item isKindOfClass:[HomePlayRoomModel class]]) {
HomePlayRoomModel * roomInfo = (HomePlayRoomModel *)item;
if (roomInfo.uid.length > 0) {
@@ -241,8 +363,7 @@
model.width = [UILabel getWidthWithText:@(model.onlineNum).stringValue height:kGetScaleWidth(12) font:kFontBold(10)]+1;
}
self.datasource = [NSMutableArray arrayWithArray:list];
self.datasource = [NSMutableArray arrayWithArray:[self processDataSourceForLayout:list]];
[self.collectionView reloadData];
}
@@ -251,7 +372,9 @@
}
- (NSMutableArray *)insertBannerData:(NSArray *)firstPageList {
NSMutableArray *mutableArrayA = [firstPageList mutableCopy];
// banner
NSArray *processedList = [self processDataSourceForLayout:firstPageList];
NSMutableArray *mutableArrayA = [processedList mutableCopy];
if (self.bannerInfoList.count > 0) {
NSInteger insertIndex = 5;
@@ -274,9 +397,9 @@
if(self.page == 1){
self.datasource = [self insertBannerData:list];
}else{
[self.datasource addObjectsFromArray:list];
NSArray *processedList = [self processDataSourceForLayout:list];
[self.datasource addObjectsFromArray:processedList];
}
[self.collectionView reloadData];
[[NSNotificationCenter defaultCenter]postNotificationName:@"khomeVCRefreshComplete" object:nil];
[self.collectionView.mj_footer endRefreshing];
@@ -311,9 +434,10 @@
font:kFontBold(10)] + 1;
}
if(self.page == 1){
self.datasource = [NSMutableArray arrayWithArray:rooms];
self.datasource = [NSMutableArray arrayWithArray:[self processDataSourceForLayout:rooms]];
}else{
[self.datasource addObjectsFromArray:rooms];
NSArray *processedList = [self processDataSourceForLayout:rooms];
[self.datasource addObjectsFromArray:processedList];
}
[self.collectionView reloadData];
}
@@ -327,9 +451,10 @@
font:kFontBold(10)] + 1;
}
if(self.page == 1){
self.datasource = [NSMutableArray arrayWithArray:rooms];
self.datasource = [NSMutableArray arrayWithArray:[self processDataSourceForLayout:rooms]];
}else{
[self.datasource addObjectsFromArray:rooms];
NSArray *processedList = [self processDataSourceForLayout:rooms];
[self.datasource addObjectsFromArray:processedList];
}
[self.collectionView reloadData];
}
@@ -385,6 +510,7 @@
[_collectionView registerClass:[XPNewHomePartyCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([XPNewHomePartyCollectionViewCell class])];
[_collectionView registerClass:[XPGuildEmptyCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([XPGuildEmptyCollectionViewCell class])];
[_collectionView registerClass:[HomePartyBannerCell class] forCellWithReuseIdentifier:NSStringFromClass([HomePartyBannerCell class])];
[_collectionView registerClass:[XPBlankCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([XPBlankCollectionViewCell class])];
}
return _collectionView;
}