feat:新商城增加 svga 播放处理
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -151,3 +151,4 @@ iOS/Podfile.lock
|
||||
Podfile.lock
|
||||
*/.DS_Store
|
||||
.DS_Store
|
||||
YuMi.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
|
||||
|
@@ -496,6 +496,9 @@
|
||||
23FF42762AA6E1480055733C /* XPHomeRecommendOtherRoomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23FF42752AA6E1480055733C /* XPHomeRecommendOtherRoomView.m */; };
|
||||
23FF42792AA6E19C0055733C /* HomeMenuSourceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 23FF42782AA6E19C0055733C /* HomeMenuSourceModel.m */; };
|
||||
23FF428E2AAB2D3A0055733C /* XPCandyTreeBuyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23FF428D2AAB2D3A0055733C /* XPCandyTreeBuyView.m */; };
|
||||
4C6E1F752CEAEC3C0073D0A3 /* ShoppingMallTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6E1F742CEAEC3C0073D0A3 /* ShoppingMallTagView.m */; };
|
||||
4C6E1F792CEB12780073D0A3 /* UIView+GradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6E1F782CEB12780073D0A3 /* UIView+GradientLayer.m */; };
|
||||
4C6E1F7C2CEB25B10073D0A3 /* ShoppingMallItemPreview.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6E1F7B2CEB25B10073D0A3 /* ShoppingMallItemPreview.m */; };
|
||||
540EC1D02C89925F00F3BF0D /* GiftComboView.m in Sources */ = {isa = PBXBuildFile; fileRef = 540EC1CF2C89925F00F3BF0D /* GiftComboView.m */; };
|
||||
540EC1D32C89998500F3BF0D /* GiftComboManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 540EC1D22C89998500F3BF0D /* GiftComboManager.m */; };
|
||||
5412E0F42C4E460300FDD668 /* XPMineCenterAgencyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5412E0F32C4E460300FDD668 /* XPMineCenterAgencyView.m */; };
|
||||
@@ -2575,6 +2578,12 @@
|
||||
23FF42782AA6E19C0055733C /* HomeMenuSourceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeMenuSourceModel.m; sourceTree = "<group>"; };
|
||||
23FF428C2AAB2D3A0055733C /* XPCandyTreeBuyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPCandyTreeBuyView.h; sourceTree = "<group>"; };
|
||||
23FF428D2AAB2D3A0055733C /* XPCandyTreeBuyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPCandyTreeBuyView.m; sourceTree = "<group>"; };
|
||||
4C6E1F732CEAEC3C0073D0A3 /* ShoppingMallTagView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShoppingMallTagView.h; sourceTree = "<group>"; };
|
||||
4C6E1F742CEAEC3C0073D0A3 /* ShoppingMallTagView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShoppingMallTagView.m; sourceTree = "<group>"; };
|
||||
4C6E1F772CEB12780073D0A3 /* UIView+GradientLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+GradientLayer.h"; sourceTree = "<group>"; };
|
||||
4C6E1F782CEB12780073D0A3 /* UIView+GradientLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIView+GradientLayer.m"; sourceTree = "<group>"; };
|
||||
4C6E1F7A2CEB25B10073D0A3 /* ShoppingMallItemPreview.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShoppingMallItemPreview.h; sourceTree = "<group>"; };
|
||||
4C6E1F7B2CEB25B10073D0A3 /* ShoppingMallItemPreview.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShoppingMallItemPreview.m; sourceTree = "<group>"; };
|
||||
540EC1CE2C89925F00F3BF0D /* GiftComboView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GiftComboView.h; sourceTree = "<group>"; };
|
||||
540EC1CF2C89925F00F3BF0D /* GiftComboView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GiftComboView.m; sourceTree = "<group>"; };
|
||||
540EC1D12C89998500F3BF0D /* GiftComboManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GiftComboManager.h; sourceTree = "<group>"; };
|
||||
@@ -5157,6 +5166,7 @@
|
||||
189DD56C26DF5B5400AB55B1 /* CustomUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C6E1F762CEB12560073D0A3 /* UIViewGradientLayer */,
|
||||
237700D42BC7D3DC00D661F1 /* MSRTL */,
|
||||
E8FE3C292994D0CC0006C6C7 /* SwitchView */,
|
||||
E81E09C6290F719C00A1F410 /* Adbvertise */,
|
||||
@@ -6578,6 +6588,15 @@
|
||||
path = SubViews;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4C6E1F762CEB12560073D0A3 /* UIViewGradientLayer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C6E1F772CEB12780073D0A3 /* UIView+GradientLayer.h */,
|
||||
4C6E1F782CEB12780073D0A3 /* UIView+GradientLayer.m */,
|
||||
);
|
||||
path = UIViewGradientLayer;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
54283CE22CE48884009729B5 /* ShoppingMall */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -6589,6 +6608,10 @@
|
||||
54283CE72CE48ABB009729B5 /* MyDressingViewController.m */,
|
||||
54283CE92CE48B71009729B5 /* ShoppingMallCategoryListView.h */,
|
||||
54283CEA2CE48B71009729B5 /* ShoppingMallCategoryListView.m */,
|
||||
4C6E1F732CEAEC3C0073D0A3 /* ShoppingMallTagView.h */,
|
||||
4C6E1F742CEAEC3C0073D0A3 /* ShoppingMallTagView.m */,
|
||||
4C6E1F7A2CEB25B10073D0A3 /* ShoppingMallItemPreview.h */,
|
||||
4C6E1F7B2CEB25B10073D0A3 /* ShoppingMallItemPreview.m */,
|
||||
);
|
||||
path = ShoppingMall;
|
||||
sourceTree = "<group>";
|
||||
@@ -11822,6 +11845,7 @@
|
||||
2331C1732A5EB71000E1D940 /* XPNoblePrivilegeCell.m in Sources */,
|
||||
9B2EA7C628041EFC00ED17BF /* XPAnchorPkPanelView.m in Sources */,
|
||||
E84150BB27747BAF00A7F548 /* XPFirstRechargePresenter.m in Sources */,
|
||||
4C6E1F752CEAEC3C0073D0A3 /* ShoppingMallTagView.m in Sources */,
|
||||
E8A88D2D27E81E8700CA8837 /* RoomPKChooseUserModel.m in Sources */,
|
||||
E82325F9274E2E42003A3332 /* Api+UserCard.m in Sources */,
|
||||
238B37A62AC55A2C00BFC9D5 /* TreasureFairySendRecordModel.m in Sources */,
|
||||
@@ -12251,6 +12275,7 @@
|
||||
54E82EA82CA6940900C931D9 /* RoomBoomResultView.m in Sources */,
|
||||
23194DBB2AD13EAB00649F51 /* PILoginManager.m in Sources */,
|
||||
E8DEC99E2764A5B60078CB70 /* XPRoomMoreMenuViewController.m in Sources */,
|
||||
4C6E1F7C2CEB25B10073D0A3 /* ShoppingMallItemPreview.m in Sources */,
|
||||
E82325F2274E2DE6003A3332 /* XPUserCardViewController.m in Sources */,
|
||||
E85E7B512A4EB0D300B6D00A /* Api+Guild.m in Sources */,
|
||||
E83645682A40A2DC00E0DBE4 /* XPSkillCardPlayerManager.m in Sources */,
|
||||
@@ -12972,6 +12997,7 @@
|
||||
54C389672C24464600FD47B1 /* HomeMineRoomModel.m in Sources */,
|
||||
23E9EA792A8385CC00B792F2 /* XPTreasureFairyGiftView.m in Sources */,
|
||||
149839C7299E0B9F00F82CBF /* XPMomentListCollectionViewCell.m in Sources */,
|
||||
4C6E1F792CEB12780073D0A3 /* UIView+GradientLayer.m in Sources */,
|
||||
236BA4982BB6AFED00C7C73A /* PINoblePrivilegeEmptyCell.m in Sources */,
|
||||
E88C729C2828F37D0047FB2B /* XPRoomMusicLibraryEmptyTableViewCell.m in Sources */,
|
||||
E85E7B0A2A4EB0D200B6D00A /* XPGuildManagerPerPresenter.m in Sources */,
|
||||
|
BIN
YuMi/Assets.xcassets/1.0.30/mall_category_homepage.imageset/1@3x.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.30/mall_category_homepage.imageset/1@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
21
YuMi/Assets.xcassets/1.0.30/mall_category_homepage.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.30/mall_category_homepage.imageset/Contents.json
vendored
Normal 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
|
||||
}
|
||||
}
|
21
YuMi/Assets.xcassets/1.0.30/mall_item_preview_bg.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.30/mall_item_preview_bg.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "_s-框@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.30/mall_item_preview_bg.imageset/_s-框@3x.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.30/mall_item_preview_bg.imageset/_s-框@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 598 KiB |
21
YuMi/Assets.xcassets/1.0.30/mall_item_preview_line.imageset/Contents.json
vendored
Normal file
21
YuMi/Assets.xcassets/1.0.30/mall_item_preview_line.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "矩形 3212@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
YuMi/Assets.xcassets/1.0.30/mall_item_preview_line.imageset/矩形 3212@3x.png
vendored
Normal file
BIN
YuMi/Assets.xcassets/1.0.30/mall_item_preview_line.imageset/矩形 3212@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
37
YuMi/CustomUI/UIViewGradientLayer/UIView+GradientLayer.h
Normal file
37
YuMi/CustomUI/UIViewGradientLayer/UIView+GradientLayer.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// UIView+GradientLayer.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIView (GradientLayer)
|
||||
|
||||
/// 为视图添加渐变背景
|
||||
/// @param colors 渐变颜色数组 (NSArray<UIColor *> *)
|
||||
/// @param startPoint 渐变起点 (CGPoint)
|
||||
/// @param endPoint 渐变终点 (CGPoint)
|
||||
/// @param cornerRadius 圆角半径 (CGFloat)
|
||||
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint
|
||||
cornerRadius:(CGFloat)cornerRadius;
|
||||
|
||||
/// 移除渐变背景
|
||||
- (void)removeGradientBackground;
|
||||
|
||||
/// 更新渐变背景
|
||||
/// @param colors 渐变颜色数组 (NSArray<UIColor *> *)
|
||||
/// @param startPoint 渐变起点 (CGPoint)
|
||||
/// @param endPoint 渐变终点 (CGPoint)
|
||||
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
120
YuMi/CustomUI/UIViewGradientLayer/UIView+GradientLayer.m
Normal file
120
YuMi/CustomUI/UIViewGradientLayer/UIView+GradientLayer.m
Normal file
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// UIView+GradientLayer.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import "UIView+GradientLayer.h"
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@implementation UIView (GradientLayer)
|
||||
|
||||
static NSString * const kGradientLayerName = @"GradientLayer";
|
||||
static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
|
||||
// 添加渐变背景
|
||||
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint
|
||||
cornerRadius:(CGFloat)cornerRadius {
|
||||
// 确保移除已有的渐变背景和 KVO 监听
|
||||
[self removeGradientBackground];
|
||||
|
||||
// 创建渐变图层
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.name = kGradientLayerName;
|
||||
gradientLayer.colors = [self cgColorsFromUIColors:colors];
|
||||
gradientLayer.startPoint = startPoint;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
gradientLayer.cornerRadius = cornerRadius;
|
||||
|
||||
// 初次设置 frame
|
||||
gradientLayer.frame = self.bounds;
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
|
||||
// 添加 KVO 监听
|
||||
[self setupLayoutObserverForGradientLayer:gradientLayer];
|
||||
}
|
||||
|
||||
// 动态更新渐变背景
|
||||
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint {
|
||||
CAGradientLayer *gradientLayer = [self gradientLayer];
|
||||
if (gradientLayer) {
|
||||
gradientLayer.colors = [self cgColorsFromUIColors:colors];
|
||||
gradientLayer.startPoint = startPoint;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除渐变背景和监听
|
||||
- (void)removeGradientBackground {
|
||||
// 移除渐变图层
|
||||
CAGradientLayer *gradientLayer = [self gradientLayer];
|
||||
if (gradientLayer) {
|
||||
[gradientLayer removeFromSuperlayer];
|
||||
}
|
||||
|
||||
// 移除 KVO 监听
|
||||
if ([self hasAddedObserver]) {
|
||||
[self removeObserver:self forKeyPath:@"bounds"];
|
||||
[self setHasAddedObserver:NO];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取渐变图层
|
||||
- (CAGradientLayer *)gradientLayer {
|
||||
for (CALayer *layer in self.layer.sublayers) {
|
||||
if ([layer.name isEqualToString:kGradientLayerName] &&
|
||||
[layer isKindOfClass:[CAGradientLayer class]]) {
|
||||
return (CAGradientLayer *)layer;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// 添加 KVO 监听
|
||||
- (void)setupLayoutObserverForGradientLayer:(CAGradientLayer *)gradientLayer {
|
||||
if (![self hasAddedObserver]) {
|
||||
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:(__bridge void *)gradientLayer];
|
||||
[self setHasAddedObserver:YES];
|
||||
}
|
||||
}
|
||||
|
||||
// KVO 监听回调
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
||||
context:(void *)context {
|
||||
if ([keyPath isEqualToString:@"bounds"]) {
|
||||
CAGradientLayer *gradientLayer = (__bridge CAGradientLayer *)context;
|
||||
gradientLayer.frame = self.bounds; // 更新渐变图层的 frame
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
// 工具方法:转换颜色数组
|
||||
- (NSArray *)cgColorsFromUIColors:(NSArray<UIColor *> *)colors {
|
||||
NSMutableArray *cgColors = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
[cgColors addObject:(id)color.CGColor];
|
||||
}
|
||||
return [cgColors copy];
|
||||
}
|
||||
|
||||
// 工具方法:判断是否已注册 KVO
|
||||
- (BOOL)hasAddedObserver {
|
||||
return [objc_getAssociatedObject(self, kGradientObserverKey) boolValue];
|
||||
}
|
||||
|
||||
// 工具方法:设置是否已注册 KVO
|
||||
- (void)setHasAddedObserver:(BOOL)added {
|
||||
objc_setAssociatedObject(self, kGradientObserverKey, @(added), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -22,7 +22,7 @@ typedef void (^FetchDataForPage)(NSInteger pageIndex, FetchDataCompletion comple
|
||||
@property (nonatomic, copy) NSArray<NSDictionary<NSString *, NSNumber *> *> *items;
|
||||
@property (nonatomic, copy) FetchDataForPage fetchDataForPage;
|
||||
@property (nonatomic, copy) DidTapPlay didTapItemPlay;
|
||||
|
||||
@property(nonatomic, copy) void(^returnSelectedModel)(DressUpShopModel * _Nullable model);
|
||||
|
||||
@end
|
||||
|
||||
|
@@ -7,6 +7,54 @@
|
||||
|
||||
#import "ShoppingMallCategoryListView.h"
|
||||
|
||||
#import "ShoppingMallTagView.h"
|
||||
|
||||
@interface ShoppingMallEmptyCard : UICollectionViewCell
|
||||
|
||||
@property(nonatomic, strong) UILabel *defaultLabel;
|
||||
@property(nonatomic, strong) UIImageView *defaultImageView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShoppingMallEmptyCard
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[self.contentView addSubview:self.defaultImageView];
|
||||
[self.defaultImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self.contentView);
|
||||
make.top.mas_equalTo(self.contentView);
|
||||
make.size.mas_equalTo(CGSizeMake(110, 110));
|
||||
}];
|
||||
|
||||
[self.contentView addSubview:self.defaultLabel];
|
||||
[self.defaultLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self.contentView);
|
||||
make.top.mas_equalTo(self.defaultImageView.mas_bottom).offset(8);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UILabel *)defaultLabel {
|
||||
if (!_defaultLabel) {
|
||||
_defaultLabel = [UILabel labelInitWithText:YMLocalizedString(@"XPMomentsRecommendViewController0")
|
||||
font:kFontRegular(14)
|
||||
textColor:[UIColor colorWithWhite:1 alpha:0.4]];
|
||||
_defaultLabel.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
return _defaultLabel;
|
||||
}
|
||||
|
||||
- (UIImageView *)defaultImageView {
|
||||
if (!_defaultImageView) {
|
||||
_defaultImageView = [[UIImageView alloc] initWithImage:kImage(@"common_empty_UFO")];
|
||||
}
|
||||
return _defaultImageView;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface ShoppingMallItemCard : UICollectionViewCell
|
||||
|
||||
@property (nonatomic, strong) UIImageView *bgImageView;
|
||||
@@ -18,7 +66,9 @@
|
||||
@property (nonatomic, strong) UILabel *pricePerDayLabel;
|
||||
@property (nonatomic, strong) UILabel *description_1_label;
|
||||
@property (nonatomic, strong) UILabel *description_2_label;
|
||||
@property (nonatomic, strong) UILabel *statusLabel;
|
||||
@property (nonatomic, strong) ShoppingMallTagView *statusLabel;
|
||||
|
||||
@property (nonatomic, copy) DidTapPlay didTapPlay;
|
||||
|
||||
@property (nonatomic, copy) DidTapPlay didTapPlay;
|
||||
|
||||
@@ -84,7 +134,7 @@
|
||||
[self.contentView addSubview:self.statusLabel];
|
||||
[self.statusLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.leading.mas_equalTo(self.bgImageView).offset(1);
|
||||
make.width.mas_greaterThanOrEqualTo(50);
|
||||
make.width.mas_equalTo(50);
|
||||
make.height.mas_equalTo(22);
|
||||
}];
|
||||
}
|
||||
@@ -95,11 +145,32 @@
|
||||
_cellModel = cellModel;
|
||||
self.titleLabel.text = cellModel.name;
|
||||
self.itemImageView.imageUrl = cellModel.pic;
|
||||
self.pricePerDayLabel.attributedText = [cellModel pricePerDay];
|
||||
self.description_1_label.text = YMLocalizedString(@"1.0.30_text_1");
|
||||
self.description_2_label.text = YMLocalizedString(@"1.0.30_text_2");
|
||||
self.statusLabel.text = @"FFUFUFUFUFUFUFUFUUFUFUCKCKCKCKKCKCKCKCKCKCK";//YMLocalizedString(@"1.0.30_text_4");
|
||||
if (cellModel.vipLevel > 0) {
|
||||
self.pricePerDayLabel.attributedText = [cellModel pricePerDayForVIP];
|
||||
} else {
|
||||
self.pricePerDayLabel.attributedText = [cellModel pricePerDay];
|
||||
}
|
||||
|
||||
if (cellModel.obtainWay == 1) {
|
||||
self.pricePerDayLabel.hidden = NO;
|
||||
self.description_1_label.hidden = NO;
|
||||
self.description_2_label.hidden = YES;
|
||||
self.description_1_label.text = YMLocalizedString(@"1.0.30_text_1");
|
||||
} else {
|
||||
self.pricePerDayLabel.hidden = YES;
|
||||
self.description_1_label.hidden = YES;
|
||||
self.description_2_label.hidden = NO;
|
||||
self.description_2_label.text = YMLocalizedString(@"1.0.30_text_2");
|
||||
}
|
||||
|
||||
self.statusLabel.text = YMLocalizedString(@"1.0.30_text_4");
|
||||
self.statusLabel.hidden = (cellModel.dressLimitStatus == 0);
|
||||
|
||||
[self.statusLabel mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_equalTo([self.statusLabel textWidth]);
|
||||
}];
|
||||
[self.statusLabel layoutIfNeeded];
|
||||
|
||||
self.playButton.hidden = !([cellModel.effect.lowercaseString hasSuffix:@"svga"] || [cellModel.effect.lowercaseString hasSuffix:@"mp4"]);
|
||||
}
|
||||
|
||||
@@ -109,6 +180,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected {
|
||||
self.bgImageView.image = selected ? kImage(@"mall_item_card_selected_bg") : kImage(@"mall_item_card_normal_bg") ;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (UIImageView *)bgImageView {
|
||||
if (!_bgImageView) {
|
||||
@@ -194,21 +269,10 @@
|
||||
return _description_2_label;
|
||||
}
|
||||
|
||||
- (UILabel *)statusLabel {
|
||||
- (ShoppingMallTagView *)statusLabel {
|
||||
if (!_statusLabel) {
|
||||
// TODO: 需要单独处理
|
||||
_statusLabel = [UILabel labelInitWithText:@"" font:kFontMedium(12) textColor:UIColorFromRGB(0x51281B)];
|
||||
_statusLabel.textAlignment = NSTextAlignmentCenter;
|
||||
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.colors = @[(__bridge id)UIColorFromRGB(0xE29030).CGColor,
|
||||
(__bridge id)UIColorFromRGB(0xFCC074).CGColor];
|
||||
gradientLayer.startPoint = CGPointMake(0.0, 0.0); // 顶部中央
|
||||
gradientLayer.endPoint = CGPointMake(0.0, 1.0); // 底部中央
|
||||
gradientLayer.frame = CGRectMake(0, 0, 80, 22); // 设置渐变图层大小
|
||||
[_statusLabel.layer insertSublayer:gradientLayer atIndex:0];
|
||||
|
||||
[_statusLabel setCornerRadius:10 cornerMask:kCALayerMinXMinYCorner | kCALayerMaxXMaxYCorner];
|
||||
_statusLabel = [[ShoppingMallTagView alloc] init];
|
||||
}
|
||||
return _statusLabel;
|
||||
}
|
||||
@@ -221,6 +285,7 @@
|
||||
@property (nonatomic, strong) UILabel *title;
|
||||
@property (nonatomic, assign) BOOL isSelected;
|
||||
|
||||
|
||||
+ (ShoppingMallCategoryCard *)initCard:(NSDictionary<NSString *, NSNumber *> *)dic
|
||||
frame:(CGRect)frame;
|
||||
@end
|
||||
@@ -285,6 +350,9 @@
|
||||
case 4:
|
||||
self.icon.image = kImage(@"mall_category_bubble");
|
||||
break;
|
||||
case 5:
|
||||
self.icon.image = kImage(@"mall_category_homepage");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -305,6 +373,7 @@
|
||||
@property (nonatomic, strong) NSMutableArray<UICollectionView *> *itemViews2;
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSArray <DressUpShopModel *>*> *dataCache; // 缓存每页数据
|
||||
@property (nonatomic, strong) NSMutableSet<NSNumber *> *requestedPages; // 记录已经请求的数据页
|
||||
@property (nonatomic, strong) NSIndexPath *selectedIndexPath;
|
||||
|
||||
@end
|
||||
|
||||
@@ -383,7 +452,7 @@
|
||||
// 添加 item view-2 到 container2ScrollView
|
||||
for (int i = 0; i < items.count; i++) {
|
||||
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
|
||||
layout.itemSize = CGSizeMake((screenWidth-30) / 2 - 10, kGetScaleWidth(244));
|
||||
layout.itemSize = CGSizeZero;// CGSizeMake((screenWidth-30) / 2 - 10, kGetScaleWidth(244));
|
||||
layout.minimumInteritemSpacing = 10;
|
||||
layout.minimumLineSpacing = 10;
|
||||
layout.sectionInset = UIEdgeInsetsMake(0, 15, 10, 15);
|
||||
@@ -394,8 +463,10 @@
|
||||
collectionView.dataSource = self;
|
||||
collectionView.backgroundColor = [UIColor clearColor];
|
||||
collectionView.tag = i;
|
||||
collectionView.allowsSelection = YES;
|
||||
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
|
||||
[collectionView registerClass:[ShoppingMallItemCard class] forCellWithReuseIdentifier:@"ShoppingMallItemCard"];
|
||||
[collectionView registerClass:[ShoppingMallEmptyCard class] forCellWithReuseIdentifier:@"ShoppingMallEmptyCard"];
|
||||
[self.container2ScrollView addSubview:collectionView];
|
||||
[self.itemViews2 addObject:collectionView];
|
||||
}
|
||||
@@ -427,12 +498,8 @@
|
||||
self.fetchDataForPage(type.integerValue, ^(NSArray <DressUpShopModel *>*data) {
|
||||
@kStrongify(self);
|
||||
if (self) {
|
||||
|
||||
// 更新数据到对应的 itemView-2
|
||||
[self updateContainer2WithData:data atIndex:pageIndex];
|
||||
self.dataCache[@(pageIndex)] = data; // 缓存数据
|
||||
UICollectionView *collectionView = self.itemViews2[pageIndex];
|
||||
[collectionView reloadData];
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -444,14 +511,21 @@
|
||||
for (ShoppingMallCategoryCard *view in self.itemViews1) {
|
||||
view.isSelected = (view.tag == index);
|
||||
}
|
||||
self.selectedIndexPath = nil;
|
||||
if (self.returnSelectedModel) {
|
||||
self.returnSelectedModel(nil);
|
||||
}
|
||||
for (UICollectionView *itemView in self.itemViews2) {
|
||||
[itemView reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateContainer2WithData:(NSArray *)data atIndex:(NSInteger)index {
|
||||
- (void)updateContainer2WithData:(NSArray *)data
|
||||
atIndex:(NSInteger)index {
|
||||
self.dataCache[@(index)] = data;
|
||||
if (index < self.itemViews2.count) {
|
||||
UIView *itemView = self.itemViews2[index];
|
||||
|
||||
// 在这里更新 itemView-2 的内容
|
||||
// 可以将 data 传递到 itemView-2 中,更新其内部的 collection view 或其他 UI
|
||||
UICollectionView *itemView = self.itemViews2[index];
|
||||
[itemView reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,33 +536,68 @@
|
||||
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; // 数据项数量
|
||||
return data.count == 0 ? 1 : data.count;
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSArray *data = self.dataCache[@(collectionView.tag)];
|
||||
if (data.count == 0 ) {
|
||||
return CGSizeMake(KScreenWidth, 200);
|
||||
} else {
|
||||
return CGSizeMake((KScreenWidth-30) / 2 - 10, kGetScaleWidth(244));
|
||||
}
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
ShoppingMallItemCard *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ShoppingMallItemCard"
|
||||
forIndexPath:indexPath];
|
||||
|
||||
NSArray *data = self.dataCache[@(collectionView.tag)];
|
||||
cell.cellModel = [data xpSafeObjectAtIndex:indexPath.row];
|
||||
if (self.didTapItemPlay) {
|
||||
@kWeakify(self);
|
||||
cell.didTapPlay = ^(NSString * _Nonnull resourcePath) {
|
||||
@kStrongify(self);
|
||||
self.didTapItemPlay(resourcePath);
|
||||
};
|
||||
if (data.count == 0) {
|
||||
ShoppingMallEmptyCard *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ShoppingMallEmptyCard" forIndexPath:indexPath];
|
||||
return cell;
|
||||
} else {
|
||||
ShoppingMallItemCard *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ShoppingMallItemCard"
|
||||
forIndexPath:indexPath];
|
||||
cell.cellModel = [data xpSafeObjectAtIndex:indexPath.row];
|
||||
// 设置选中状态
|
||||
if ([indexPath isEqual:self.selectedIndexPath]) {
|
||||
cell.selected = YES;
|
||||
} else {
|
||||
cell.selected = NO;
|
||||
}
|
||||
if (self.didTapItemPlay) {
|
||||
@kWeakify(self);
|
||||
cell.didTapPlay = ^(NSString * _Nonnull resourcePath) {
|
||||
@kStrongify(self);
|
||||
self.didTapItemPlay(resourcePath);
|
||||
};
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSIndexPath *previousIndexPath = self.selectedIndexPath;
|
||||
|
||||
self.selectedIndexPath = indexPath;
|
||||
|
||||
if (self.returnSelectedModel) {
|
||||
NSArray *data = self.dataCache[@(collectionView.tag)];
|
||||
DressUpShopModel *model = [data xpSafeObjectAtIndex:indexPath.row];
|
||||
self.returnSelectedModel(model);
|
||||
}
|
||||
|
||||
NSMutableArray *indexPathsToReload = [NSMutableArray array];
|
||||
if (previousIndexPath) {
|
||||
[indexPathsToReload addObject:previousIndexPath];
|
||||
}
|
||||
[indexPathsToReload addObject:indexPath];
|
||||
[collectionView reloadItemsAtIndexPaths:indexPathsToReload];
|
||||
}
|
||||
|
||||
|
||||
|
@@ -18,7 +18,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
failure:(void(^)(NSError *error))failure;
|
||||
|
||||
- (void)buyItem:(NSString *)itemID
|
||||
type:(NSInteger)type
|
||||
success:(void(^)(id obj))success
|
||||
failure:(void(^)(NSError *error))failure;
|
||||
|
||||
|
@@ -28,7 +28,6 @@
|
||||
}
|
||||
|
||||
- (void)buyItem:(NSString *)itemID
|
||||
type:(NSInteger)type
|
||||
success:(void(^)(id obj))success
|
||||
failure:(void(^)(NSError *error))failure {
|
||||
[Api requestDressUpShopBuy:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
|
||||
|
22
YuMi/Modules/ShoppingMall/ShoppingMallItemPreview.h
Normal file
22
YuMi/Modules/ShoppingMall/ShoppingMallItemPreview.h
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// ShoppingMallItemPreview.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class DressUpShopModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ShoppingMallItemPreview : UIView
|
||||
|
||||
@property(nonatomic, copy) void(^buyWith)(DressUpShopModel *model);
|
||||
|
||||
- (instancetype)initWith:(DressUpShopModel *)model;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
173
YuMi/Modules/ShoppingMall/ShoppingMallItemPreview.m
Normal file
173
YuMi/Modules/ShoppingMall/ShoppingMallItemPreview.m
Normal file
@@ -0,0 +1,173 @@
|
||||
//
|
||||
// ShoppingMallItemPreview.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import "ShoppingMallItemPreview.h"
|
||||
#import "DressUpShopModel.h"
|
||||
|
||||
@interface ShoppingMallItemPreview ()
|
||||
|
||||
@property(nonatomic, strong) DressUpShopModel *model;
|
||||
@property(nonatomic, strong) NetImageView *itemImageView;
|
||||
@property(nonatomic, strong) UILabel *nameLabel;
|
||||
@property(nonatomic, strong) UILabel *pricePerDayLabel;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShoppingMallItemPreview
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWith:(DressUpShopModel *)model {
|
||||
if (self = [super init]) {
|
||||
[self setupUI];
|
||||
self.model = model;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setModel:(DressUpShopModel *)model {
|
||||
_model = model;
|
||||
|
||||
self.itemImageView.imageUrl = model.pic;
|
||||
self.nameLabel.text = model.name;
|
||||
self.pricePerDayLabel.attributedText = model.pricePerDay;
|
||||
}
|
||||
|
||||
- (void)setupUI {
|
||||
UIImageView *bg = [self backgroundImageView];
|
||||
[self addSubview:bg];
|
||||
[bg mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
|
||||
[self addSubview:self.itemImageView];
|
||||
[self.itemImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(32);
|
||||
make.size.mas_equalTo(CGSizeMake(155, 155));
|
||||
}];
|
||||
|
||||
[self addSubview:self.nameLabel];
|
||||
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(self.itemImageView.mas_bottom).offset(4);
|
||||
make.height.mas_equalTo(22);
|
||||
}];
|
||||
|
||||
[self addSubview:self.pricePerDayLabel];
|
||||
[self.pricePerDayLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(self.nameLabel.mas_bottom).offset(10);
|
||||
make.height.mas_equalTo(22);
|
||||
}];
|
||||
|
||||
UIImageView *line = [self line];
|
||||
[self addSubview:line];
|
||||
[line mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.trailing.mas_equalTo(self).offset(22);
|
||||
make.height.mas_equalTo(1.5);
|
||||
make.top.mas_equalTo(self.pricePerDayLabel.mas_bottom).offset(18);
|
||||
}];
|
||||
|
||||
UIButton *cancel = [self cancelButton];
|
||||
[self addSubview:cancel];
|
||||
[cancel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(line.mas_bottom).offset(20);
|
||||
make.leading.mas_equalTo(46);
|
||||
make.size.mas_equalTo(CGSizeMake(90, 32));
|
||||
}];
|
||||
|
||||
UIButton *buy = [self buyButton];
|
||||
[self addSubview:buy];
|
||||
[buy mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(line.mas_bottom).offset(20);
|
||||
make.trailing.mas_equalTo(-46);
|
||||
make.size.mas_equalTo(CGSizeMake(90, 32));
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (void)didTapCancel {
|
||||
[TTPopup dismiss];
|
||||
}
|
||||
|
||||
- (void)didTapBuy {
|
||||
if (self.buyWith) {
|
||||
self.buyWith(self.model);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (UIImageView *)backgroundImageView {
|
||||
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:kImage(@"mall_item_preview_bg")];
|
||||
bgImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
return bgImageView;
|
||||
}
|
||||
|
||||
- (NetImageView *)itemImageView {
|
||||
if (!_itemImageView) {
|
||||
_itemImageView = [[NetImageView alloc] init];
|
||||
_itemImageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
}
|
||||
return _itemImageView;
|
||||
}
|
||||
|
||||
- (UILabel *)nameLabel {
|
||||
if (!_nameLabel) {
|
||||
_nameLabel = [UILabel labelInitWithText:@"" font:kFontMedium(14) textColor:UIColorFromRGB(0xd9e7f7)];
|
||||
_nameLabel.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
return _nameLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)pricePerDayLabel {
|
||||
if (!_pricePerDayLabel) {
|
||||
_pricePerDayLabel = [[UILabel alloc] init];
|
||||
_pricePerDayLabel.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
return _pricePerDayLabel;
|
||||
}
|
||||
|
||||
- (UIImageView *)line {
|
||||
UIImageView *line = [[UIImageView alloc] initWithImage:kImage(@"mall_item_preview_line")];
|
||||
line.contentMode = UIViewContentModeScaleAspectFill;
|
||||
return line;
|
||||
}
|
||||
|
||||
- (UIButton *)cancelButton {
|
||||
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[b setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.3]];
|
||||
[b setAttributedTitle:[[NSAttributedString alloc] initWithString:YMLocalizedString(@"XPShareView7")
|
||||
attributes:@{NSFontAttributeName: kFontMedium(14),
|
||||
NSForegroundColorAttributeName: [UIColor whiteColor]}]
|
||||
forState:UIControlStateNormal];
|
||||
[b addTarget:self action:@selector(didTapCancel) forControlEvents:UIControlEventTouchUpInside];
|
||||
[b setCornerRadius:16];
|
||||
return b;
|
||||
}
|
||||
|
||||
- (UIButton *)buyButton {
|
||||
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[b addGradientBackgroundWithColors:@[UIColorFromRGB(0xFFE3B2), UIColorFromRGB(0xE9A71D)]
|
||||
startPoint:CGPointMake(0.0, 0.5)
|
||||
endPoint:CGPointMake(1.0, 0.5)
|
||||
cornerRadius:16];
|
||||
[b setAttributedTitle:[[NSAttributedString alloc] initWithString:YMLocalizedString(@"XPDressUpShopCardTableViewCell2")
|
||||
attributes:@{NSFontAttributeName: kFontMedium(14),
|
||||
NSForegroundColorAttributeName: UIColorFromRGB(0x51281b)}]
|
||||
forState:UIControlStateNormal];
|
||||
[b addTarget:self action:@selector(didTapBuy) forControlEvents:UIControlEventTouchUpInside];
|
||||
[b setCornerRadius:16];
|
||||
return b;
|
||||
}
|
||||
|
||||
@end
|
20
YuMi/Modules/ShoppingMall/ShoppingMallTagView.h
Normal file
20
YuMi/Modules/ShoppingMall/ShoppingMallTagView.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// ShoppingMallTagView.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ShoppingMallTagView : UIView
|
||||
|
||||
@property(nonatomic, copy) NSString *text;
|
||||
|
||||
- (CGFloat)textWidth;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
58
YuMi/Modules/ShoppingMall/ShoppingMallTagView.m
Normal file
58
YuMi/Modules/ShoppingMall/ShoppingMallTagView.m
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// ShoppingMallTagView.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import "ShoppingMallTagView.h"
|
||||
|
||||
@interface ShoppingMallTagView ()
|
||||
|
||||
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
|
||||
@property(nonatomic, strong) UILabel *label;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShoppingMallTagView
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
[self setCornerRadius:10
|
||||
cornerMask:kCALayerMinXMinYCorner | kCALayerMaxXMaxYCorner];
|
||||
self.clipsToBounds = YES;
|
||||
|
||||
[self addGradientBackgroundWithColors:@[UIColorFromRGB(0xE29030), UIColorFromRGB(0xFCC074)]
|
||||
startPoint:CGPointMake(0.0, 0.0)
|
||||
endPoint:CGPointMake(0.0, 1.0)
|
||||
cornerRadius:0];
|
||||
|
||||
[self addSubview:self.label];
|
||||
[self.label mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text {
|
||||
_text = text;
|
||||
self.label.text = text;
|
||||
}
|
||||
|
||||
- (CGFloat)textWidth {
|
||||
return [self.text boundingRectWithSize:CGSizeMake(KScreenWidth/3, kFontMedium(12).lineHeight)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
|
||||
attributes:@{NSFontAttributeName: kFontMedium(12)}
|
||||
context:nil].size.width + 20;
|
||||
}
|
||||
|
||||
- (UILabel *)label {
|
||||
if (!_label) {
|
||||
_label = [UILabel labelInitWithText:@"" font:kFontMedium(12) textColor:UIColorFromRGB(0x51281B)];
|
||||
_label.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
return _label;
|
||||
}
|
||||
|
||||
@end
|
@@ -10,14 +10,35 @@
|
||||
#import <SVGA.h>
|
||||
#import <QGVAPWrapView.h>
|
||||
|
||||
#import "MyDressingViewController.h"
|
||||
|
||||
#import "ShoppingMallItemPreview.h"
|
||||
#import "ShoppingMallDataPresent.h"
|
||||
#import "ShoppingMallCategoryListView.h"
|
||||
|
||||
static NSArray<NSDictionary<NSString *, NSNumber *> *> *DressUpOptions(void) {
|
||||
return @[
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController2") : @1}, // 座驾
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController1") : @0}, // 头饰
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController3") : @2}, // 铭牌
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController4") : @3}, // 资料卡
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController5") : @4}, // 聊天气泡
|
||||
@{YMLocalizedString(@"1.0.30_text_9") : @5} // 個人頁裝飾
|
||||
];
|
||||
}
|
||||
|
||||
@interface ShoppingMallViewController ()
|
||||
|
||||
@property (nonatomic, strong) UIView *playEffectMask;
|
||||
@property (nonatomic, strong) VAPView *mp4Effect;
|
||||
@property (nonatomic, strong) SVGAImageView *svgaEffect;
|
||||
@property(nonatomic, strong) UIView *bottomControlArea;
|
||||
@property(nonatomic, strong) UILabel *bottomControlPriceLabel;
|
||||
@property(nonatomic, strong) UIButton *bottomControlBuyButton;
|
||||
@property(nonatomic, strong) UIButton *bottomControlGiveButton;
|
||||
|
||||
@property(nonatomic, strong) DressUpShopModel *selectedModel;
|
||||
@property(nonatomic, strong) UIActivityIndicatorView *loading;
|
||||
|
||||
@end
|
||||
|
||||
@@ -34,6 +55,17 @@
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self setupUI];
|
||||
}
|
||||
|
||||
- (void)setupUI {
|
||||
[self setupBackground];
|
||||
[self setupNavigationBar];
|
||||
[self setupBottomControlBar];
|
||||
[self setupContentList];
|
||||
}
|
||||
|
||||
- (void)setupBackground {
|
||||
self.view.backgroundColor = UIColorFromRGB(0x02061D);
|
||||
UIImageView *topBG = [[UIImageView alloc] initWithImage:kImage(@"mall_top_bg")];
|
||||
[self.view addSubview:topBG];
|
||||
@@ -41,15 +73,61 @@
|
||||
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)];
|
||||
// 设置数据请求回调
|
||||
- (void)setupNavigationBar {
|
||||
UILabel *titleLabel = [self titleLabel];
|
||||
UIButton *backButton = [self backButton];
|
||||
UIButton *myDressButton = [self myDressButton];
|
||||
[self.view addSubview:titleLabel];
|
||||
[self.view addSubview:backButton];
|
||||
[self.view addSubview:myDressButton];
|
||||
|
||||
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self.view);
|
||||
make.top.mas_equalTo(self.view).offset(44 + 11);
|
||||
make.height.mas_equalTo(22);
|
||||
}];
|
||||
|
||||
[backButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(self.view).offset(16);
|
||||
make.centerY.mas_equalTo(titleLabel);
|
||||
make.size.mas_equalTo(CGSizeMake(22, 22));
|
||||
}];
|
||||
|
||||
[myDressButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.trailing.mas_equalTo(self.view).offset(-16);
|
||||
make.centerY.mas_equalTo(titleLabel);
|
||||
make.size.mas_equalTo(CGSizeMake(102, 22));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setupBottomControlBar {
|
||||
[self.view addSubview:self.bottomControlArea];
|
||||
[self.bottomControlArea mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.leading.trailing.mas_equalTo(self.view);
|
||||
make.height.mas_equalTo(80 + kSafeAreaBottomHeight);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setupContentList {
|
||||
NSInteger top = kNavigationHeight;
|
||||
NSInteger bottom = 80 + kSafeAreaBottomHeight;
|
||||
ShoppingMallCategoryListView *listView = [[ShoppingMallCategoryListView alloc] initWithFrame:CGRectMake(0, top, KScreenWidth, KScreenHeight - top - bottom)];
|
||||
@kWeakify(self);
|
||||
listView.fetchDataForPage = ^(NSInteger pageIndex, FetchDataCompletion completion) {
|
||||
// 模拟网络请求或 API 数据请求
|
||||
@kStrongify(self);
|
||||
[self fetchDataForPage:pageIndex completion:completion];
|
||||
[self fetchDataForPage:pageIndex
|
||||
completion:completion];
|
||||
};
|
||||
listView.didTapItemPlay = ^(NSString * _Nonnull resourcePath) {
|
||||
@kStrongify(self);
|
||||
[self playItemEffect:resourcePath];
|
||||
};
|
||||
listView.returnSelectedModel = ^(DressUpShopModel * _Nonnull model) {
|
||||
@kStrongify(self);
|
||||
self.selectedModel = model;
|
||||
[self updateBottomControlArea];
|
||||
};
|
||||
listView.didTapItemPlay = ^(NSString * _Nonnull resourcePath) {
|
||||
@kStrongify(self);
|
||||
@@ -57,16 +135,12 @@
|
||||
};
|
||||
[self.view addSubview:listView];
|
||||
|
||||
listView.items = @[@{YMLocalizedString(@"XPMineDressUpViewController2") : @1}, // 座驾
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController1") : @0}, // 头饰
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController3") : @2}, // 铭牌
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController4") : @3}, // 资料卡
|
||||
@{YMLocalizedString(@"XPMineDressUpViewController5") : @4} // 聊天气泡
|
||||
];
|
||||
listView.items = DressUpOptions();
|
||||
}
|
||||
|
||||
- (void)fetchDataForPage:(NSInteger)pageIndex completion:(FetchDataCompletion)completion {
|
||||
|
||||
#pragma mark -
|
||||
- (void)fetchDataForPage:(NSInteger)pageIndex
|
||||
completion:(FetchDataCompletion)completion {
|
||||
[self.presenter loadCategoryItems:pageIndex success:^(NSArray <DressUpShopModel *>* array) {
|
||||
if (completion) {
|
||||
completion(array);
|
||||
@@ -76,18 +150,81 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateBottomControlArea {
|
||||
if (self.selectedModel) {
|
||||
self.bottomControlPriceLabel.attributedText = self.selectedModel.pricePerDay;
|
||||
} else {
|
||||
self.bottomControlPriceLabel.text = @"";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didTapBuy:(id)sender {
|
||||
if (!self.selectedModel) {
|
||||
return;
|
||||
}
|
||||
ShoppingMallItemPreview *preview = [[ShoppingMallItemPreview alloc] initWith:self.selectedModel];
|
||||
preview.frame = CGRectMake(0, 0, 284, 353);
|
||||
[TTPopup popupView:preview style:TTPopupStyleAlert];
|
||||
@kWeakify(self);
|
||||
[preview setBuyWith:^(DressUpShopModel * _Nonnull model) {
|
||||
@kStrongify(self);
|
||||
@kWeakify(self);
|
||||
[self.presenter buyItem:model.dressUpId
|
||||
success:^(id _Nonnull obj) {
|
||||
@kStrongify(self);
|
||||
[TTPopup dismiss];
|
||||
[self showSuccessToast:YMLocalizedString(@"XPDressUpShopListViewController0")];
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
// @kStrongify(self);
|
||||
// [self showErrorToast:error.localizedDescription];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)didTapGive:(id)sender {
|
||||
if (!self.selectedModel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didTapBack {
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)didTapMyDress {
|
||||
MyDressingViewController *myDressVC = [[MyDressingViewController alloc] init];
|
||||
[self.navigationController pushViewController:myDressVC animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (void)playItemEffect:(NSString *)path {
|
||||
if (!_playEffectMask) {
|
||||
[self.view addSubview:self.playEffectMask];
|
||||
[self.playEffectMask mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self.view);
|
||||
}];
|
||||
|
||||
[self.playEffectMask addSubview:self.svgaEffect];
|
||||
[self.svgaEffect mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self.playEffectMask).insets(UIEdgeInsetsMake(0, 0, 0, 0));
|
||||
}];
|
||||
}
|
||||
self.playEffectMask.hidden = NO;
|
||||
[self.loading startAnimating];
|
||||
|
||||
if ([path.lowercaseString hasSuffix:@"svga"]) {
|
||||
@kWeakify(self);
|
||||
SVGAParser *p = [[SVGAParser alloc] init];
|
||||
[p parseWithURL:[NSURL URLWithString:path]
|
||||
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
|
||||
@kStrongify(self);
|
||||
[self.loading stopAnimating];
|
||||
self.svgaEffect.hidden = NO;
|
||||
self.svgaEffect.videoItem = videoItem;
|
||||
[self.svgaEffect startAnimation];
|
||||
} failureBlock:^(NSError * _Nullable error) {
|
||||
|
||||
@kStrongify(self);
|
||||
[self stopItemSVGAEffect];
|
||||
}];
|
||||
} else if ([path.lowercaseString hasSuffix:@"mp4"]) {
|
||||
|
||||
@@ -95,17 +232,21 @@
|
||||
}
|
||||
|
||||
- (void)stopItemSVGAEffect {
|
||||
[self.loading stopAnimating];
|
||||
[self.svgaEffect stopAnimation];
|
||||
self.svgaEffect.hidden = YES;
|
||||
self.playEffectMask.hidden = YES;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
- (UIView *)playEffectMask {
|
||||
if (!_playEffectMask) {
|
||||
_playEffectMask = [[UIView alloc] initWithFrame:self.view.bounds];
|
||||
_playEffectMask.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5f];
|
||||
[_playEffectMask addSubview:self.loading];
|
||||
[self.loading mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.center.mas_equalTo(_playEffectMask);
|
||||
}];
|
||||
}
|
||||
return _playEffectMask;
|
||||
}
|
||||
@@ -119,20 +260,136 @@
|
||||
_svgaEffect.clearsAfterStop = YES;
|
||||
_svgaEffect.hidden = YES;
|
||||
|
||||
if (!_playEffectMask) {
|
||||
[self.view addSubview:self.playEffectMask];
|
||||
}
|
||||
|
||||
[self.view addSubview:_svgaEffect];
|
||||
[_svgaEffect mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.leading.trailing.mas_equalTo(self.view);
|
||||
make.height.mas_equalTo(KScreenHeight - 100);
|
||||
}];
|
||||
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stopItemSVGAEffect)];
|
||||
[_svgaEffect addGestureRecognizer:tap];
|
||||
}
|
||||
return _svgaEffect;
|
||||
}
|
||||
|
||||
- (UIView *)bottomControlArea {
|
||||
if (!_bottomControlArea) {
|
||||
_bottomControlArea = [[UIView alloc] init];
|
||||
[_bottomControlArea addGradientBackgroundWithColors:@[UIColorFromRGB(0x012E4D), UIColorFromRGB(0x0F1435)]
|
||||
startPoint:CGPointMake(0.5, 0)
|
||||
endPoint:CGPointMake(0.5, 1)
|
||||
cornerRadius:0];
|
||||
|
||||
[_bottomControlArea addSubview:self.bottomControlPriceLabel];
|
||||
[self.bottomControlPriceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.top.mas_equalTo(16);
|
||||
}];
|
||||
|
||||
[_bottomControlArea addSubview:self.bottomControlGiveButton];
|
||||
[self.bottomControlGiveButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(14);
|
||||
make.trailing.mas_equalTo(-16);
|
||||
make.size.mas_equalTo(CGSizeMake(74, 32));
|
||||
}];
|
||||
|
||||
[_bottomControlArea addSubview:self.bottomControlBuyButton];
|
||||
[self.bottomControlBuyButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(14);
|
||||
make.trailing.mas_equalTo(self.bottomControlGiveButton.mas_leading).offset(-8);
|
||||
make.size.mas_equalTo(CGSizeMake(74, 32));
|
||||
}];
|
||||
}
|
||||
return _bottomControlArea;
|
||||
}
|
||||
|
||||
- (UILabel *)bottomControlPriceLabel {
|
||||
if (!_bottomControlPriceLabel) {
|
||||
_bottomControlPriceLabel = [[UILabel alloc] init];
|
||||
}
|
||||
return _bottomControlPriceLabel;
|
||||
}
|
||||
|
||||
- (UIButton *)bottomControlBuyButton {
|
||||
if (!_bottomControlBuyButton) {
|
||||
_bottomControlBuyButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_bottomControlBuyButton setTitle:YMLocalizedString(@"1.0.30_text_5") forState:UIControlStateNormal];
|
||||
[_bottomControlBuyButton setTitleColor:UIColorFromRGB(0x51281B) forState:UIControlStateNormal];
|
||||
[_bottomControlBuyButton addGradientBackgroundWithColors:@[UIColorFromRGB(0xFFE3B2), UIColorFromRGB(0xE9A71D)]
|
||||
startPoint:CGPointMake(0.0, 0.5)
|
||||
endPoint:CGPointMake(1.0, 0.5)
|
||||
cornerRadius:16];
|
||||
[_bottomControlBuyButton addTarget:self
|
||||
action:@selector(didTapBuy:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _bottomControlBuyButton;
|
||||
}
|
||||
|
||||
- (UIButton *)bottomControlGiveButton {
|
||||
if (!_bottomControlGiveButton) {
|
||||
_bottomControlGiveButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_bottomControlGiveButton setTitle:YMLocalizedString(@"1.0.30_text_6") forState:UIControlStateNormal];
|
||||
[_bottomControlGiveButton setTitleColor:UIColorFromRGB(0x172055) forState:UIControlStateNormal];
|
||||
[_bottomControlGiveButton addGradientBackgroundWithColors:@[UIColorFromRGB(0xB2FCFF), UIColorFromRGB(0x4DA2EA)]
|
||||
startPoint:CGPointMake(0.0, 0.5)
|
||||
endPoint:CGPointMake(1.0, 0.5)
|
||||
cornerRadius:16];
|
||||
[_bottomControlGiveButton addTarget:self
|
||||
action:@selector(didTapGive:)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _bottomControlGiveButton;
|
||||
}
|
||||
|
||||
- (UIButton *)backButton {
|
||||
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[b setImage:[kImage(@"vip_center_back_button") ms_SetImageForRTL]
|
||||
forState:UIControlStateNormal];
|
||||
[b addTarget:self
|
||||
action:@selector(didTapBack)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
return b;
|
||||
}
|
||||
|
||||
- (UILabel *)titleLabel {
|
||||
UILabel *label = [[UILabel alloc] init];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.font = kFontMedium(17);
|
||||
label.text = YMLocalizedString(@"1.0.30_text_7");
|
||||
label.textColor = UIColorFromRGB(0xD9E7F7);
|
||||
return label;
|
||||
}
|
||||
|
||||
- (UIButton *)myDressButton {
|
||||
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[b addGradientBackgroundWithColors:@[UIColorFromRGB(0x004A4F), UIColorFromRGB(0x11215B)]
|
||||
startPoint:CGPointMake(0.5, 0.0)
|
||||
endPoint:CGPointMake(0.5, 1.0)
|
||||
cornerRadius:11];
|
||||
[b setCornerRadius:11
|
||||
corners:kCALayerMaxXMaxYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMinXMinYCorner
|
||||
borderWidth:1
|
||||
borderColor:UIColorFromRGB(0x75B4DF)];
|
||||
[b setAttributedTitle:[[NSAttributedString alloc] initWithString:YMLocalizedString(@"1.0.30_text_8")
|
||||
attributes:@{NSFontAttributeName: kFontMedium(12),
|
||||
NSForegroundColorAttributeName: UIColorFromRGB(0xd9e7f7)}]
|
||||
forState:UIControlStateNormal];
|
||||
[b setImage:kImage(@"mall_my_icon") forState:UIControlStateNormal];
|
||||
|
||||
CGFloat spacing = 2.0; // 图像和标题之间的间距
|
||||
b.imageEdgeInsets = UIEdgeInsetsMake(0, b.titleLabel.intrinsicContentSize.width + spacing, 0, -b.titleLabel.intrinsicContentSize.width - spacing);
|
||||
b.titleEdgeInsets = UIEdgeInsetsMake(0, -b.imageView.frame.size.width*2, 0, b.imageView.frame.size.width*2 + spacing);
|
||||
|
||||
// 设置按钮的整体布局和样式
|
||||
b.contentEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, spacing);
|
||||
|
||||
[b addTarget:self action:@selector(didTapMyDress) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
- (UIActivityIndicatorView *)loading {
|
||||
if (!_loading) {
|
||||
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
|
||||
indicator.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
indicator.hidesWhenStopped = YES;
|
||||
_loading = indicator;
|
||||
}
|
||||
return _loading;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -34,8 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
// "折扣价格"
|
||||
@property (nonatomic, assign) CGFloat discountPrice;
|
||||
|
||||
|
||||
// "vip等级"
|
||||
// "vip等级", 0 表示当前用户不是 VIP
|
||||
@property (nonatomic, assign) NSInteger vipLevel;
|
||||
|
||||
// "vip等级对应的折扣百分比 * 100"
|
||||
@@ -48,6 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, assign) NSInteger obtainWay;
|
||||
|
||||
- (NSMutableAttributedString *)pricePerDay;
|
||||
- (NSMutableAttributedString *)pricePerDayForVIP;
|
||||
|
||||
@end
|
||||
|
||||
|
@@ -33,7 +33,16 @@
|
||||
NSFontAttributeName: kFontSemibold(15),
|
||||
NSForegroundColorAttributeName: UIColorFromRGB(0xF8CE1F)
|
||||
};
|
||||
NSAttributedString *priceString = [[NSAttributedString alloc] initWithString:@(self.dressPrice).stringValue attributes:priceAttributes];
|
||||
NSString *formattedPriceString;
|
||||
|
||||
//TODO: 修改为支持 0-1-2 位小数
|
||||
|
||||
if (fmod(self.discountPrice, 1.0) == 0.0) {
|
||||
formattedPriceString = [NSString stringWithFormat:@"%ld", (long)self.dressPrice];
|
||||
} else {
|
||||
formattedPriceString = [NSString stringWithFormat:@"%.2ld", (long)self.dressPrice];
|
||||
}
|
||||
NSAttributedString *priceString = [[NSAttributedString alloc] initWithString:formattedPriceString attributes:priceAttributes];
|
||||
[attributedString appendAttributedString:priceString];
|
||||
|
||||
// 4. 添加 day 文本,字体常规,颜色 #F8CE1F,字体大小 12
|
||||
@@ -41,10 +50,72 @@
|
||||
NSFontAttributeName: kFontRegular(12),
|
||||
NSForegroundColorAttributeName: UIColorFromRGB(0xF8CE1F)
|
||||
};
|
||||
NSAttributedString *dayString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"/%ldD", (long)self.dressDay] attributes:dayAttributes];
|
||||
NSString *formattedString;
|
||||
if (fmod(self.dressDay, 1.0) == 0.0) {
|
||||
formattedString = [NSString stringWithFormat:@"/%.0ldD ", (long)self.dressDay];
|
||||
} else {
|
||||
formattedString = [NSString stringWithFormat:@"/%.2ldD ", (long)self.dressDay];
|
||||
}
|
||||
NSAttributedString *dayString = [[NSAttributedString alloc] initWithString:formattedString
|
||||
attributes:dayAttributes];
|
||||
[attributedString appendAttributedString:dayString];
|
||||
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
- (NSMutableAttributedString *)pricePerDayForVIP {
|
||||
// 创建一个 NSMutableAttributedString 来存放最终的结果
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
|
||||
|
||||
// 1. 添加金币图片
|
||||
NSTextAttachment *coinAttachment = [[NSTextAttachment alloc] init];
|
||||
coinAttachment.image = kImage(@"moli_money_icon"); // 替换为你的金币图片名称
|
||||
coinAttachment.bounds = CGRectMake(0, -2, 18, 18); // 设置图片大小和位置,偏移量适当调整
|
||||
NSAttributedString *coinString = [NSAttributedString attributedStringWithAttachment:coinAttachment];
|
||||
[attributedString appendAttributedString:coinString];
|
||||
|
||||
// 2. 添加空格
|
||||
NSAttributedString *spaceString = [[NSAttributedString alloc] initWithString:@" "];
|
||||
[attributedString appendAttributedString:spaceString];
|
||||
|
||||
// 3. 添加 price 文本,字体加粗,颜色 #F8CE1F,字体大小 25
|
||||
NSDictionary *priceAttributes = @{
|
||||
NSFontAttributeName: kFontSemibold(15),
|
||||
NSForegroundColorAttributeName: UIColorFromRGB(0xF8CE1F)
|
||||
};
|
||||
NSString *formattedPriceString;
|
||||
if (fmod(self.discountPrice, 1.0) == 0.0) {
|
||||
formattedPriceString = [NSString stringWithFormat:@"%.f", self.discountPrice];
|
||||
} else {
|
||||
formattedPriceString = [NSString stringWithFormat:@"%.2f", self.discountPrice];
|
||||
}
|
||||
NSAttributedString *priceString = [[NSAttributedString alloc] initWithString:formattedPriceString attributes:priceAttributes];
|
||||
[attributedString appendAttributedString:priceString];
|
||||
|
||||
// 4. 添加 day 文本,字体常规,颜色 #F8CE1F,字体大小 12
|
||||
NSDictionary *dayAttributes = @{
|
||||
NSFontAttributeName: kFontRegular(12),
|
||||
NSForegroundColorAttributeName: UIColorFromRGB(0xF8CE1F)
|
||||
};
|
||||
NSString *formattedString;
|
||||
if (fmod(self.dressDay, 1.0) == 0.0) {
|
||||
formattedString = [NSString stringWithFormat:@"/%.0ldD ", (long)self.dressDay];
|
||||
} else {
|
||||
formattedString = [NSString stringWithFormat:@"/%.2ldD ", (long)self.dressDay];
|
||||
}
|
||||
NSAttributedString *dayString = [[NSAttributedString alloc] initWithString:formattedString attributes:dayAttributes];
|
||||
[attributedString appendAttributedString:dayString];
|
||||
|
||||
NSDictionary *originalPriceAttributes = @{
|
||||
NSFontAttributeName: kFontRegular(12),
|
||||
NSForegroundColorAttributeName: UIColorRGBAlpha(0xD9E7F7, 0.5f),
|
||||
NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle), // 单条删除线
|
||||
NSStrikethroughColorAttributeName: UIColorRGBAlpha(0xD9E7F7, 0.5f) // 删除线颜色
|
||||
};
|
||||
NSAttributedString *originalPriceString = [[NSAttributedString alloc] initWithString:@(self.dressPrice).stringValue attributes:originalPriceAttributes];
|
||||
[attributedString appendAttributedString:originalPriceString];
|
||||
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -55,7 +55,7 @@
|
||||
}
|
||||
|
||||
+ (void)clientConfig:(HttpRequestHelperCompletion)completion {
|
||||
[HttpRequestHelper request:@"client/config" method:HttpRequestHelperMethodGET params:@{@"timeoutInterval":@(2)} completion:completion];
|
||||
[HttpRequestHelper request:@"client/config" method:HttpRequestHelperMethodGET params:@{@"timeoutInterval":@(5)} completion:completion];
|
||||
}
|
||||
|
||||
|
||||
|
@@ -74,6 +74,8 @@
|
||||
if (timeout > 0) {
|
||||
manager.requestSerializer.timeoutInterval = timeout;
|
||||
}
|
||||
} else {
|
||||
manager.requestSerializer.timeoutInterval = 30;
|
||||
}
|
||||
|
||||
params = [MSParamsDecode msDecodeParams:[params mutableCopy] ];
|
||||
|
@@ -38,6 +38,7 @@ isEnterprise = [bundleID isEqualToString:@"com.hflighting.yumi"];\
|
||||
#import "NSString+Utils.h"
|
||||
#import "UIButton+EnlargeTouchArea.h"
|
||||
#import "UIView+Corner.h"
|
||||
#import "UIView+GradientLayer.h"
|
||||
#import "UILabel+Utils.h"
|
||||
#import "TTPopup.h"
|
||||
#import "NSDate+DateUtils.h"
|
||||
|
@@ -4004,3 +4004,8 @@ ineHeadView12" = "الحمل";
|
||||
"1.0.30_text_2" = "Only get by event, cannot buy";
|
||||
"1.0.30_text_3" = "Exclusive for VIP%@";
|
||||
"1.0.30_text_4" = "Limited";
|
||||
"1.0.30_text_5" = "Buy";
|
||||
"1.0.30_text_6" = "Give";
|
||||
"1.0.30_text_7" = "Mall";
|
||||
"1.0.30_text_8" = "My Dress";
|
||||
"1.0.30_text_9" = "Homepage";
|
||||
|
@@ -3797,3 +3797,8 @@
|
||||
"1.0.30_text_2" = "Only get by event, cannot buy";
|
||||
"1.0.30_text_3" = "Exclusive for VIP%@";
|
||||
"1.0.30_text_4" = "Limited";
|
||||
"1.0.30_text_5" = "Buy";
|
||||
"1.0.30_text_6" = "Give";
|
||||
"1.0.30_text_7" = "Mall";
|
||||
"1.0.30_text_8" = "My Dress";
|
||||
"1.0.30_text_9" = "Homepage";
|
||||
|
@@ -3583,3 +3583,8 @@
|
||||
"1.0.30_text_2" = "Only get by event, cannot buy";
|
||||
"1.0.30_text_3" = "Exclusive for VIP%@";
|
||||
"1.0.30_text_4" = "Limited";
|
||||
"1.0.30_text_5" = "Buy";
|
||||
"1.0.30_text_6" = "Give";
|
||||
"1.0.30_text_7" = "Mall";
|
||||
"1.0.30_text_8" = "My Dress";
|
||||
"1.0.30_text_9" = "Homepage";
|
||||
|
@@ -3455,3 +3455,8 @@
|
||||
"1.0.30_text_2" = "Only get by event, cannot buy";
|
||||
"1.0.30_text_3" = "Exclusive for VIP%@";
|
||||
"1.0.30_text_4" = "Limited";
|
||||
"1.0.30_text_5" = "Buy";
|
||||
"1.0.30_text_6" = "Give";
|
||||
"1.0.30_text_7" = "Mall";
|
||||
"1.0.30_text_8" = "My Dress";
|
||||
"1.0.30_text_9" = "Homepage";
|
||||
|
Reference in New Issue
Block a user