feat: 新商城框架

This commit is contained in:
eggmanQQQ
2024-11-13 19:17:06 +08:00
parent 9a3aab22e9
commit e47259c82c
38 changed files with 789 additions and 7 deletions

View File

@@ -501,6 +501,10 @@
5412E0F42C4E460300FDD668 /* XPMineCenterAgencyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5412E0F32C4E460300FDD668 /* XPMineCenterAgencyView.m */; };
5412E0FD2C52512100FDD668 /* RoomBottomEntranceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5412E0FC2C52512100FDD668 /* RoomBottomEntranceModel.m */; };
541DD9552C1EDEFB00B616C4 /* XPHomePagingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 541DD9542C1EDEFB00B616C4 /* XPHomePagingViewController.m */; };
54283CE52CE48A69009729B5 /* ShoppingMallViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 54283CE42CE48A69009729B5 /* ShoppingMallViewController.m */; };
54283CE82CE48ABB009729B5 /* MyDressingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 54283CE72CE48ABB009729B5 /* MyDressingViewController.m */; };
54283CEB2CE48B71009729B5 /* ShoppingMallCategoryListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 54283CEA2CE48B71009729B5 /* ShoppingMallCategoryListView.m */; };
54283CEE2CE48B97009729B5 /* ShoppingMallDataPresent.m in Sources */ = {isa = PBXBuildFile; fileRef = 54283CED2CE48B97009729B5 /* ShoppingMallDataPresent.m */; };
544879EA2CD215F400D58DC1 /* CustomRoomBGCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 544879E92CD215F400D58DC1 /* CustomRoomBGCell.m */; };
544879ED2CD22A6B00D58DC1 /* CustomRoomBGPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 544879EC2CD22A6B00D58DC1 /* CustomRoomBGPresenter.m */; };
544879F02CD22D4B00D58DC1 /* CustomRoomBGItemModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 544879EF2CD22D4B00D58DC1 /* CustomRoomBGItemModel.m */; };
@@ -2581,6 +2585,14 @@
5412E0FC2C52512100FDD668 /* RoomBottomEntranceModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomBottomEntranceModel.m; sourceTree = "<group>"; };
541DD9532C1EDEFB00B616C4 /* XPHomePagingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPHomePagingViewController.h; sourceTree = "<group>"; };
541DD9542C1EDEFB00B616C4 /* XPHomePagingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPHomePagingViewController.m; sourceTree = "<group>"; };
54283CE32CE48A69009729B5 /* ShoppingMallViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShoppingMallViewController.h; sourceTree = "<group>"; };
54283CE42CE48A69009729B5 /* ShoppingMallViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShoppingMallViewController.m; sourceTree = "<group>"; };
54283CE62CE48ABB009729B5 /* MyDressingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyDressingViewController.h; sourceTree = "<group>"; };
54283CE72CE48ABB009729B5 /* MyDressingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyDressingViewController.m; sourceTree = "<group>"; };
54283CE92CE48B71009729B5 /* ShoppingMallCategoryListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShoppingMallCategoryListView.h; sourceTree = "<group>"; };
54283CEA2CE48B71009729B5 /* ShoppingMallCategoryListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShoppingMallCategoryListView.m; sourceTree = "<group>"; };
54283CEC2CE48B97009729B5 /* ShoppingMallDataPresent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShoppingMallDataPresent.h; sourceTree = "<group>"; };
54283CED2CE48B97009729B5 /* ShoppingMallDataPresent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShoppingMallDataPresent.m; sourceTree = "<group>"; };
54435F2C2CC89D4600F4884B /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
54435F2D2CC89D4600F4884B /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
544879E82CD215F400D58DC1 /* CustomRoomBGCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CustomRoomBGCell.h; sourceTree = "<group>"; };
@@ -5106,6 +5118,7 @@
189DD56126DE45F800AB55B1 /* Modules */ = {
isa = PBXGroup;
children = (
54283CE22CE48884009729B5 /* ShoppingMall */,
E87E624F2A3F54B5002F68C9 /* YMNewHome */,
18E7B1B426E8B2960064BC9B /* YMTabbar */,
E81DCCC4282B620A0039E5C5 /* YMMonents */,
@@ -6565,6 +6578,21 @@
path = SubViews;
sourceTree = "<group>";
};
54283CE22CE48884009729B5 /* ShoppingMall */ = {
isa = PBXGroup;
children = (
54283CEC2CE48B97009729B5 /* ShoppingMallDataPresent.h */,
54283CED2CE48B97009729B5 /* ShoppingMallDataPresent.m */,
54283CE32CE48A69009729B5 /* ShoppingMallViewController.h */,
54283CE42CE48A69009729B5 /* ShoppingMallViewController.m */,
54283CE62CE48ABB009729B5 /* MyDressingViewController.h */,
54283CE72CE48ABB009729B5 /* MyDressingViewController.m */,
54283CE92CE48B71009729B5 /* ShoppingMallCategoryListView.h */,
54283CEA2CE48B71009729B5 /* ShoppingMallCategoryListView.m */,
);
path = ShoppingMall;
sourceTree = "<group>";
};
5461040A2CD4B3CB00066B21 /* banner */ = {
isa = PBXGroup;
children = (
@@ -11679,6 +11707,7 @@
9BD9A18027A0EFC7004186FE /* XPMineVisitorTableViewCell.m in Sources */,
233423D02AAEFBC300B1253F /* PICandyTreeSetModel.m in Sources */,
E85E7B112A4EB0D200B6D00A /* GuildPersonIncomeRecordModel.m in Sources */,
54283CEB2CE48B71009729B5 /* ShoppingMallCategoryListView.m in Sources */,
548E01CC2C3FB1C70071C83D /* i18nGiftNameMap.m in Sources */,
9BD2ECD2288F833B00F5CD9A /* XPMineFootPrintModel.m in Sources */,
E824546626F5FF6000BE8163 /* XPMineResetPayPasswordProtocol.h in Sources */,
@@ -12113,6 +12142,7 @@
E8778AE72988C1E000CF139B /* XPSessionHelloEnterView.m in Sources */,
18A61BD7274F7F6900A09A54 /* NetImageConfig.m in Sources */,
E8C21501274B76F60079E6BF /* XPRoomAnimationHitView.m in Sources */,
54283CE82CE48ABB009729B5 /* MyDressingViewController.m in Sources */,
E84A2E9F2A5287D200D6AF8A /* XPIncomeRecordGoldDetailsView.m in Sources */,
233423C72AAEE5C600B1253F /* XPCandyTreeBuySuccessView.m in Sources */,
E873EB0F28098D500071030D /* MessageContentGiftView.m in Sources */,
@@ -12694,6 +12724,7 @@
E85E7BA92A4EC99300B6D00A /* XPMineConfirmGiveDiamondView.m in Sources */,
54C9A1102C3D3E1700C6D970 /* XPMineGameMateOrderView.m in Sources */,
E85E7BA72A4EC99300B6D00A /* XPMineGiveDiamondPasswordView.m in Sources */,
54283CEE2CE48B97009729B5 /* ShoppingMallDataPresent.m in Sources */,
2331C1742A5EB71000E1D940 /* XPNobleCenterResidueView.m in Sources */,
E80E2377299A47F60013FD40 /* AESUtils.m in Sources */,
E81060E229876E9100B772F0 /* MessageImageModel.m in Sources */,
@@ -12701,6 +12732,7 @@
E80E09AE2A41336500CD2BE7 /* XPWebViewNavView.m in Sources */,
E85E7B2D2A4EB0D300B6D00A /* XPGuildHeaderView.m in Sources */,
E85E7B542A4EB4AD00B6D00A /* XPMineGuildListModel.m in Sources */,
54283CE52CE48A69009729B5 /* ShoppingMallViewController.m in Sources */,
9BCE6144277D657600CC0358 /* XPReleaseRadioTableViewCell.m in Sources */,
186A534D26FC6ED900D67B2C /* TTActionSheetView.m in Sources */,
E81060E529876FF300B772F0 /* MessageAudioModel.m in Sources */,

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1@3x (3).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1@3x (2).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "矩形 2941@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1@3x (1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "矩形 2941@3x (1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "1@3x (4).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "切图 56@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "播放@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "4@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,16 @@
//
// MyDressingViewController.h
// YuMi
//
// Created by P on 2024/11/13.
//
#import "MvpViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface MyDressingViewController : MvpViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,31 @@
//
// MyDressingViewController.m
// YuMi
//
// Created by P on 2024/11/13.
//
#import "MyDressingViewController.h"
@interface MyDressingViewController ()
@end
@implementation MyDressingViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end

View File

@@ -0,0 +1,26 @@
//
// ShoppingMallCategoryListView.h
// YuMi
//
// Created by P on 2024/11/13.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^FetchDataCompletion)(NSArray *data);
typedef void (^FetchDataForPage)(NSInteger pageIndex, FetchDataCompletion completion);
@interface ShoppingMallCategoryListView : UIView
// 名称:类型
@property (nonatomic, copy) NSArray<NSDictionary<NSString *, NSNumber *> *> *items;
@property (nonatomic, copy) FetchDataForPage fetchDataForPage;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,293 @@
//
// ShoppingMallCategoryListView.m
// YuMi
//
// Created by P on 2024/11/13.
//
#import "ShoppingMallCategoryListView.h"
@interface ShoppingMallItemCard : UICollectionViewCell
@end
@implementation ShoppingMallItemCard
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// TODO:
// MARK:
}
return self;
}
@end
@interface ShoppingMallCategoryCard : UIView
@property (nonatomic, strong) UIImageView *selectedStatusView;
@property (nonatomic, strong) UIImageView *icon;
@property (nonatomic, strong) UILabel *title;
@property (nonatomic, assign) BOOL isSelected;
+ (ShoppingMallCategoryCard *)initCard:(NSDictionary<NSString *, NSNumber *> *)dic
frame:(CGRect)frame;
@end
@implementation ShoppingMallCategoryCard
+ (ShoppingMallCategoryCard *)initCard:(NSDictionary<NSString *, NSNumber *> *)dic
frame:(CGRect)frame {
ShoppingMallCategoryCard *card = [[ShoppingMallCategoryCard alloc] initWithFrame:frame];
[card update:dic];
card.isSelected = NO;
return card;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setCornerRadius:8];
self.selectedStatusView = [[UIImageView alloc] initWithFrame:self.bounds];
self.selectedStatusView.image = kImage(@"mall_category_normal_bg");
[self addSubview:self.selectedStatusView];
self.icon = [[UIImageView alloc] init];
[self addSubview:self.icon];
[self.icon mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self);
make.top.mas_equalTo(8);
make.size.mas_equalTo(CGSizeMake(38, 38));
}];
self.title = [UILabel labelInitWithText:@""
font:kFontRegular(11)
textColor:UIColorFromRGB(0xD9E7F7)];
self.title.textAlignment = NSTextAlignmentCenter;
[self addSubview:self.title];
[self.title mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(-11);
make.leading.trailing.mas_equalTo(self);
make.height.mas_equalTo(14);
}];
}
return self;
}
- (void)update:(NSDictionary *)dic {
NSNumber *type = [dic.allValues firstObject];
NSString *key = [dic.allKeys firstObject];
self.title.text = key;
switch (type.integerValue) {
case 0:
self.icon.image = kImage(@"mall_category_headdress");
break;
case 1:
self.icon.image = kImage(@"mall_category_vehicle");
break;
case 2:
self.icon.image = kImage(@"mall_category_nameplate");
break;
case 3:
self.icon.image = kImage(@"mall_category_room_card");
break;
case 4:
self.icon.image = kImage(@"mall_category_bubble");
break;
default:
break;
}
}
- (void)setIsSelected:(BOOL)isSelected {
_isSelected = isSelected;
self.selectedStatusView.image = isSelected ? kImage(@"mall_category_selected_bg") : kImage(@"mall_category_normal_bg");
self.title.alpha = isSelected ? 1 : 0.5;
}
@end
@interface ShoppingMallCategoryListView () <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIScrollViewDelegate>
@property (nonatomic, strong) UIScrollView *container1ScrollView;
@property (nonatomic, strong) UIScrollView *container2ScrollView;
@property (nonatomic, strong) NSMutableArray<ShoppingMallCategoryCard *> *itemViews1;
@property (nonatomic, strong) NSMutableArray<UICollectionView *> *itemViews2;
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSArray *> *dataCache; //
@property (nonatomic, strong) NSMutableSet<NSNumber *> *requestedPages; //
@end
@implementation ShoppingMallCategoryListView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupUI];
// [self loadDataForPageAtIndex:0];
}
return self;
}
- (instancetype)init {
if (self = [super init]) {
[self setupUI];
}
return self;
}
- (void)setupUI {
self.backgroundColor = [UIColor clearColor];
self.dataCache = @{}.mutableCopy;
self.requestedPages = [NSMutableSet set]; //
self.container2ScrollView.delegate = self; //
CGFloat screenWidth = KScreenWidth;
CGFloat screenHeight = self.bounds.size.height;
// -1 ()
self.container1ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(15, 0, screenWidth-15, 90)];
self.container1ScrollView.contentInset = UIEdgeInsetsMake(0, 15, 0, 15);
self.container1ScrollView.showsHorizontalScrollIndicator = NO;
self.container1ScrollView.clipsToBounds = NO;
[self addSubview:self.container1ScrollView];
// -2 ()
self.container2ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, screenWidth, screenHeight - 100)];
self.container2ScrollView.pagingEnabled = YES;
self.container2ScrollView.delegate = self;
self.container2ScrollView.showsHorizontalScrollIndicator = NO;
[self addSubview:self.container2ScrollView];
self.itemViews1 = [NSMutableArray array];
self.itemViews2 = [NSMutableArray array];
}
- (void)setItems:(NSArray *)items {
_items = items;
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat container1ItemWidth = kGetScaleWidth(70);
CGFloat container1ItemHeight = 84;
CGFloat container1ItemSpacing = 12;
// container1 container2
self.container1ScrollView.contentSize = CGSizeMake(items.count * (container1ItemWidth + container1ItemSpacing), 90);
self.container2ScrollView.contentSize = CGSizeMake(items.count * screenWidth, self.container2ScrollView.frame.size.height);
// item view-1 container1ScrollView
for (int i = 0; i < items.count; i++) {
ShoppingMallCategoryCard *itemView1 = [ShoppingMallCategoryCard initCard:[items xpSafeObjectAtIndex:i]
frame:CGRectMake(i * (container1ItemWidth + container1ItemSpacing),
3,
container1ItemWidth,
container1ItemHeight)];
itemView1.tag = i;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleItemTap:)];
[itemView1 addGestureRecognizer:tapGesture];
[self.container1ScrollView addSubview:itemView1];
[self.itemViews1 addObject:itemView1];
}
// item view-2 container2ScrollView
for (int i = 0; i < items.count; i++) {
// UIView *itemView2 = [[UIView alloc] initWithFrame:CGRectMake(i * screenWidth, 0, screenWidth, self.container2ScrollView.frame.size.height)];
// itemView2.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake((screenWidth-30) / 2 - 10, kGetScaleWidth(244));
layout.minimumInteritemSpacing = 10;
layout.minimumLineSpacing = 10;
layout.sectionInset = UIEdgeInsetsMake(0, 15, 10, 15);
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(i * screenWidth, 0, screenWidth, self.container2ScrollView.frame.size.height)
collectionViewLayout:layout];
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.backgroundColor = [UIColor clearColor];
collectionView.tag = i;
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
[self.container2ScrollView addSubview:collectionView];
[self.itemViews2 addObject:collectionView];
}
[self updateSelectionForItemAtIndex:0];
[self loadDataForPageAtIndex:0];
}
// item view-1 item view-2
- (void)handleItemTap:(UITapGestureRecognizer *)gesture {
NSInteger index = gesture.view.tag;
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
[self.container2ScrollView setContentOffset:CGPointMake(index * screenWidth, 0) animated:YES];
[self updateSelectionForItemAtIndex:index];
[self loadDataForPageAtIndex:index];
}
//
- (void)loadDataForPageAtIndex:(NSInteger)pageIndex {
//
if (![self.requestedPages containsObject:@(pageIndex)]) {
[self.requestedPages addObject:@(pageIndex)]; //
// 使
if (self.fetchDataForPage) {
@kWeakify(self);
self.fetchDataForPage(pageIndex, ^(NSArray *data) {
@kStrongify(self);
if (self) {
// itemView-2
[self updateContainer2WithData:data atIndex:pageIndex];
self.dataCache[@(pageIndex)] = data; //
UICollectionView *collectionView = self.itemViews2[pageIndex];
[collectionView reloadData];
}
});
}
}
}
// item view-1
- (void)updateSelectionForItemAtIndex:(NSInteger)index {
for (ShoppingMallCategoryCard *view in self.itemViews1) {
view.isSelected = (view.tag == index);
}
}
- (void)updateContainer2WithData:(NSArray *)data atIndex:(NSInteger)index {
if (index < self.itemViews2.count) {
UIView *itemView = self.itemViews2[index];
// itemView-2
// data itemView-2 collection view UI
}
}
#pragma mark - UIScrollView Delegate
// container2ScrollView item view-1
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == self.container2ScrollView) {
NSInteger pageIndex = round(scrollView.contentOffset.x / scrollView.frame.size.width);
[self updateSelectionForItemAtIndex:pageIndex];
[self loadDataForPageAtIndex:pageIndex];
// pageControl container1ScrollView
// [self updateContainer1SelectionForPage:pageIndex];
}
}
#pragma mark - UICollectionView Delegate & DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSArray *data = self.dataCache[@(collectionView.tag)];
return data.count; //
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0f green:arc4random()%255/255.0f blue:arc4random()%255/255.0f alpha:1]; // Placeholder color
return cell;
}
@end

View File

@@ -0,0 +1,26 @@
//
// ShoppingMallDataPresent.h
// YuMi
//
// Created by P on 2024/11/13.
//
#import "BaseMvpPresenter.h"
NS_ASSUME_NONNULL_BEGIN
@interface ShoppingMallDataPresent : BaseMvpPresenter
/// 获取装扮商城列表
/// @param type 类型 0铭牌1头饰2座驾3资料卡4聊天气泡
- (void)loadCategoryItems:(NSInteger)type
success:(void(^)(id obj))success
failure:(void(^)(NSError *error))failure;
- (void)buyItem:(NSString *)itemID
type:(NSInteger)type
success:(void(^)(id obj))success
failure:(void(^)(NSError *error))failure;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,45 @@
//
// ShoppingMallDataPresent.m
// YuMi
//
// Created by P on 2024/11/13.
//
#import "ShoppingMallDataPresent.h"
#import "Api+DressUp.h"
@implementation ShoppingMallDataPresent
- (void)loadCategoryItems:(NSInteger)type
success:(nonnull void (^)(id _Nonnull))success
failure:(nonnull void (^)(NSError * _Nonnull))failure{
[Api requestDressUpShopList:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
if (success) {
success(data.data);
}
} fail:^(NSInteger code, NSString * _Nullable msg) {
if (failure) {
failure([NSError errorWithDomain:msg code:code userInfo:nil]);
}
} showLoading:YES errorToast:YES]
dressType:@(type).stringValue];
}
- (void)buyItem:(NSString *)itemID
type:(NSInteger)type
success:(void(^)(id obj))success
failure:(void(^)(NSError *error))failure {
[Api requestDressUpShopBuy:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
if (success) {
success(data.data);
}
} fail:^(NSInteger code, NSString * _Nullable msg) {
if (failure) {
failure([NSError errorWithDomain:msg code:code userInfo:nil]);
}
} showLoading:YES errorToast:YES]
id:itemID];
}
@end

View File

@@ -0,0 +1,16 @@
//
// ShoppingMallViewController.h
// YuMi
//
// Created by P on 2024/11/13.
//
#import "MvpViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ShoppingMallViewController : MvpViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,70 @@
//
// ShoppingMallViewController.m
// YuMi
//
// Created by P on 2024/11/13.
//
#import "ShoppingMallViewController.h"
#import "ShoppingMallDataPresent.h"
#import "ShoppingMallCategoryListView.h"
@interface ShoppingMallViewController ()
@end
@implementation ShoppingMallViewController
- (ShoppingMallDataPresent *)createPresenter {
return [[ShoppingMallDataPresent alloc] init];
}
- (BOOL)isHiddenNavBar {
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColorFromRGB(0x02061D);
UIImageView *topBG = [[UIImageView alloc] initWithImage:kImage(@"mall_top_bg")];
[self.view addSubview:topBG];
[topBG mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.leading.trailing.mas_equalTo(self.view);
make.height.mas_equalTo(kGetScaleWidth(200));
}];
NSInteger top = kNavigationHeight + 56;
ShoppingMallCategoryListView *listView = [[ShoppingMallCategoryListView alloc] initWithFrame:CGRectMake(0, top, KScreenWidth, KScreenHeight - top)];
//
@kWeakify(self);
listView.fetchDataForPage = ^(NSInteger pageIndex, FetchDataCompletion completion) {
// API
@kStrongify(self);
[self fetchDataForPage:pageIndex completion:completion];
};
[self.view addSubview:listView];
listView.items = @[@{YMLocalizedString(@"XPMineDressUpViewController2") : @1}, //
@{YMLocalizedString(@"XPMineDressUpViewController1") : @0}, //
@{YMLocalizedString(@"XPMineDressUpViewController3") : @2}, //
@{YMLocalizedString(@"XPMineDressUpViewController4") : @3}, //
@{YMLocalizedString(@"XPMineDressUpViewController5") : @4} //
];
}
- (void)fetchDataForPage:(NSInteger)pageIndex completion:(FetchDataCompletion)completion {
// completion
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSMutableArray *data = [NSMutableArray array];
for (int i = 0; i < 20; i++) {
[data addObject:@(i + arc4random()%100 * 20)];
}
if (completion) {
completion(data);
}
});
}
@end

View File

@@ -76,7 +76,7 @@ NS_ASSUME_NONNULL_BEGIN
/// 活动
/// @param completion 完成
/// @param type 类型 2 房间的 1 首页的 3 我的装扮
+ (void)dressupBannerList:(HttpRequestHelperCompletion)completion type:(NSString *)type;
+ (void)dressUpBannerList:(HttpRequestHelperCompletion)completion type:(NSString *)type;
#pragma mark - 装扮商城

View File

@@ -112,7 +112,7 @@
///
/// @param completion
/// @param type 2 1 3
+ (void)dressupBannerList:(HttpRequestHelperCompletion)completion type:(NSString *)type {
+ (void)dressUpBannerList:(HttpRequestHelperCompletion)completion type:(NSString *)type {
NSString * fang = [NSString stringFromBase64String:@"aG9tZS9iYW5uZXI="];/// home/banner
[self makeRequest:fang method:HttpRequestHelperMethodGET completion:completion, __FUNCTION__, type, nil];
}

View File

@@ -161,7 +161,7 @@
- (void)requestActivityList {
@kWeakify(self);
[Api dressupBannerList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
[Api dressUpBannerList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
if (code == 200) {
NSArray <ActivityInfoModel *>* array = [ActivityInfoModel modelsWithArray:data.data];
@@ -283,7 +283,11 @@
}
- (NSArray<NSString *> *)titles {
return @[YMLocalizedString(@"XPMineDressUpViewController1"), YMLocalizedString(@"XPMineDressUpViewController2"), YMLocalizedString(@"XPMineDressUpViewController3"), YMLocalizedString(@"XPMineDressUpViewController4"), YMLocalizedString(@"XPDressUpShopViewController6")];
return @[YMLocalizedString(@"XPMineDressUpViewController1"),
YMLocalizedString(@"XPMineDressUpViewController2"),
YMLocalizedString(@"XPMineDressUpViewController3"),
YMLocalizedString(@"XPMineDressUpViewController4"),
YMLocalizedString(@"XPDressUpShopViewController6")];
}
- (XPDressUpShopListViewController *)headwearView {

View File

@@ -84,7 +84,7 @@
}
- (void)requestActivityList {
[Api dressupBannerList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
[Api dressUpBannerList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200) {
NSArray <ActivityInfoModel *>* array = [ActivityInfoModel modelsWithArray:data.data];
if (array.count <= 0) {

View File

@@ -14,6 +14,8 @@
#import "Api+Gift.h"
#import "XPGiftStorage.h"
#import "ShoppingMallViewController.h"
@interface XPHomePagingViewController () <UIPageViewControllerDelegate, UIPageViewControllerDataSource>
@property (nonatomic, strong) UIView *topControlView;
@@ -164,6 +166,11 @@
#pragma mark -
- (void)didTapMineButton {
ShoppingMallViewController *vc = [[ShoppingMallViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
return;
[self.pageContainer setViewControllers:@[self.viewControllers[1]]
direction:UIPageViewControllerNavigationDirectionReverse
animated:NO

View File

@@ -794,7 +794,6 @@ UIKIT_EXTERN NSString *kTabShowAnchorCardKey;
self.viewControllers = [viewControllers copy];
self.selectedIndex = 0;
if (isLogin) {
for (int i = 0; i < self.viewControllers.count; i++) {
UIViewController *itemVc = self.viewControllers[i];

View File

@@ -676,7 +676,7 @@
"XPMineDressUpViewController0" = "My Item";
"XPMineDressUpViewController1" = "Avatar Frame";
"XPMineDressUpViewController2" = "Mount";
"XPMineDressUpViewController2" = "Vehicle";
"XPMineDressUpViewController3" = "Nameplate";
"XPMineDressUpViewController4" = "Profile Card";
"XPMineDressUpViewController5" = "Chat Bubble";

View File

@@ -12,6 +12,7 @@
///XPCandyTreeMoreView.m
"XPCandyTreeMoreView0" = "更多";
"XPCandyTreeMoreView0" = "更多";
"XPCandyTreeMoreView2" = "獲獎記錄";
"XPCandyTreeMoreView3" = "玩法規則";
"XPCandyTreeMoreView4" = "允許將中獎消息對外展示";