Commit 44f547e2 by suolong

实现付费房 观众界面

parent b4e716bf
Showing with 648 additions and 17 deletions
......@@ -16,21 +16,5 @@
stopOnStyle = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "557ED31B-F4DE-4254-9E50-0D51EFABE241"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Controller/FUSLiveMainViewController.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1648"
endingLineNumber = "1648"
landmarkName = "-payRoomSwitch:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
......@@ -1788,6 +1788,12 @@
A1B2C3D4E5F60718293A4B6D /* FUSPayRoomViewerPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F60718293A4B6B /* FUSPayRoomViewerPopView.m */; };
A1B2C3D4E5F60718293A4B8B /* FUSPayRoomViewerListView.h in Headers */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F60718293A4B7C /* FUSPayRoomViewerListView.h */; };
A1B2C3D4E5F60718293A4B8D /* FUSPayRoomViewerListView.m in Sources */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F60718293A4B7D /* FUSPayRoomViewerListView.m */; };
7C2A1F1A3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C2A1F0B3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.h */; };
7C2A1F1B3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C2A1F0C3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.m */; };
7C2A1F1C3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C2A1F0D3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.h */; };
7C2A1F1D3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C2A1F0E3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.m */; };
7C2A1F243A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C2A1F223A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.h */; };
7C2A1F253A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C2A1F233A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.m */; };
BEEAB2642D34CC60008CD059 /* FUSLiveStartContentWarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEEAB2602D34CC60008CD059 /* FUSLiveStartContentWarningView.swift */; };
BEEAB2652D34CC60008CD059 /* FUSLiveStartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEEAB2622D34CC60008CD059 /* FUSLiveStartView.swift */; };
BEEAB2662D34CC60008CD059 /* FUSLiveStartBeautyFavoritesEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEEAB2552D34CC60008CD059 /* FUSLiveStartBeautyFavoritesEditView.swift */; };
......@@ -4152,6 +4158,12 @@
A1B2C3D4E5F60718293A4B6B /* FUSPayRoomViewerPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSPayRoomViewerPopView.m; sourceTree = "<group>"; };
A1B2C3D4E5F60718293A4B7C /* FUSPayRoomViewerListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FUSPayRoomViewerListView.h; sourceTree = "<group>"; };
A1B2C3D4E5F60718293A4B7D /* FUSPayRoomViewerListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSPayRoomViewerListView.m; sourceTree = "<group>"; };
7C2A1F0B3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FUSPayRoomCompanionDataModel.h; sourceTree = "<group>"; };
7C2A1F0C3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSPayRoomCompanionDataModel.m; sourceTree = "<group>"; };
7C2A1F0D3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FUSPayRoomCompanionPopView.h; sourceTree = "<group>"; };
7C2A1F0E3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSPayRoomCompanionPopView.m; sourceTree = "<group>"; };
7C2A1F223A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FUSPayRoomCompanionProgressView.h; sourceTree = "<group>"; };
7C2A1F233A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FUSPayRoomCompanionProgressView.m; sourceTree = "<group>"; };
BEEAB2552D34CC60008CD059 /* FUSLiveStartBeautyFavoritesEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FUSLiveStartBeautyFavoritesEditView.swift; sourceTree = "<group>"; };
BEEAB2562D34CC60008CD059 /* FUSLiveStartBeautyFavoritesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FUSLiveStartBeautyFavoritesView.swift; sourceTree = "<group>"; };
BEEAB2572D34CC60008CD059 /* FUSLiveStartBeautySetItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FUSLiveStartBeautySetItemView.swift; sourceTree = "<group>"; };
......@@ -7760,6 +7772,7 @@
isa = PBXGroup;
children = (
00F0A0FE2F9A000100C0FFEE /* EntryMain */,
7C2A1F0A3A1D4D2C9A0B1C2D /* CompanionPopup */,
00F0A0112F5F0A1B00C0FFEE /* FusAnchorPayRoomView.h */,
00F0A0122F5F0A1B00C0FFEE /* FusAnchorPayRoomView.m */,
A1B2C3D4E5F60718293A4B6A /* FUSPayRoomViewerPopView.h */,
......@@ -7770,6 +7783,19 @@
path = PayRoom;
sourceTree = "<group>";
};
7C2A1F0A3A1D4D2C9A0B1C2D /* CompanionPopup */ = {
isa = PBXGroup;
children = (
7C2A1F0B3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.h */,
7C2A1F0C3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.m */,
7C2A1F0D3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.h */,
7C2A1F0E3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.m */,
7C2A1F223A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.h */,
7C2A1F233A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.m */,
);
path = CompanionPopup;
sourceTree = "<group>";
};
BEEAB2712D34F8DF008CD059 /* PopularListView */ = {
isa = PBXGroup;
children = (
......@@ -8800,6 +8826,9 @@
00F0A1122F9A000100C0FFEE /* FUSPayRoomFrostedGlassDataModel.h in Headers */,
A1B2C3D4E5F60718293A4B6C /* FUSPayRoomViewerPopView.h in Headers */,
A1B2C3D4E5F60718293A4B8B /* FUSPayRoomViewerListView.h in Headers */,
7C2A1F1A3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.h in Headers */,
7C2A1F1C3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.h in Headers */,
7C2A1F243A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.h in Headers */,
BED65A572C5B745F00668116 /* FUSLiveTreasureBoxRecordDetailView.h in Headers */,
BED658C02C5B745E00668116 /* FUSLiveHalfWebViewCatalogueView.h in Headers */,
BED65A542C5B745F00668116 /* FUSLiveTreasureBoxListIconView.h in Headers */,
......@@ -10743,6 +10772,9 @@
00F0A1132F9A000100C0FFEE /* FUSPayRoomFrostedGlassDataModel.m in Sources */,
A1B2C3D4E5F60718293A4B6D /* FUSPayRoomViewerPopView.m in Sources */,
A1B2C3D4E5F60718293A4B8D /* FUSPayRoomViewerListView.m in Sources */,
7C2A1F1B3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionDataModel.m in Sources */,
7C2A1F1D3A1D4D2C9A0B1C2D /* FUSPayRoomCompanionPopView.m in Sources */,
7C2A1F253A1D4D2C9A0B1C2D /* FUSPayRoomCompanionProgressView.m in Sources */,
BED65ABF2C5B745F00668116 /* FUSHomeNovaListBroadcastHelper.m in Sources */,
BED6598C2C5B745E00668116 /* FUSLiveDewIncreaseView.m in Sources */,
BE189DE22C733B460008418B /* FSRSettingOnlineViewController.m in Sources */,
{
"images" : [
{
"filename" : "live_anchor_progress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "live_anchor_progress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "live_anchor_progress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
......@@ -29,6 +29,9 @@
#import "FUSPayRoomEntryMainView.h"
#import "FUSPayRoomFrostedGlassDataModel.h"
#import "FUSPayRoomCompanionDataModel.h"
#import "FUSPayRoomCompanionPopView.h"
#import "FUSRechargeViewController.h"
#import <FirebaseAnalytics/FirebaseAnalytics.h>
......@@ -45,6 +48,11 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
*/
@property (nonatomic, strong) NSTimer *pushStreamSwitchTimer;
/// 付费屋 /payRoom/payViewing 接口返回的陪伴信息缓存(用于进房后弹窗展示)
@property (nonatomic, strong) FUSPayRoomCompanionDataModel *payRoomCompanionDataModel;
@property (nonatomic, assign) NSInteger payRoomUnitPricePerMinute;
@property (nonatomic, assign) NSInteger payRoomBillingTimeMinutes;
// 直播间 Controller,弱引用
@property (nonatomic, strong) FUSLiveMainViewController *liveVC;
......@@ -1042,11 +1050,15 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
viewModel.accompanyUserFacePaths = facePaths.copy;
NSInteger pricePerMinute = dataModel.payRoomConfigData.payUnitPrice;
NSInteger billingTime = dataModel.payRoomConfigData.billingTime;
NSInteger canCompanionTime = dataModel.userData.canCompanionTime;
NSInteger previewTime = dataModel.payRoomConfigData.previewTime;
BOOL diamondEnough = (dataModel.userData.isDiamondEnough > 0);
viewModel.primaryButtonTitle = (diamondEnough ? [NSString fus_localString:@"进入陪伴"] : [NSString fus_localString:@"马上储值进入陪伴"]);
strongSelf.payRoomUnitPricePerMinute = MAX(0, pricePerMinute);
strongSelf.payRoomBillingTimeMinutes = MAX(0, billingTime);
viewModel.trialButtonHidden = (previewTime <= 0);
if (previewTime > 0) {
viewModel.trialButtonTitle = [NSString stringWithFormat:[NSString fus_localString:@"试看%ldS"], (long)previewTime];
......@@ -1202,6 +1214,13 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
return;
}
NSDictionary *companionData = [FUSHttpHelper fus_parseJSONDictionaryLayerByLayerWithObject:dataDict[@"companionData"]];
if (![NSDictionary isNull:companionData]) {
strongSelf.payRoomCompanionDataModel = [FUSPayRoomCompanionDataModel fus_modelWithDict:companionData];
} else {
strongSelf.payRoomCompanionDataModel = nil;
}
dispatch_async(dispatch_get_main_queue(), ^{
[weakEntryView fus_dismissAnimated:YES];
[strongSelf fus_audienceJoinRoomWithRoomId:(roomId ?: @"") password:@"" behaviorSrc:@"" otherInfo:nil];
......@@ -1215,6 +1234,43 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
}];
}
- (void)fus_showPayRoomCompanionPopIfNeededWithRoomId:(NSString *)roomId
{
/// 仅观众端进房后需要提示陪伴进度
if (self.liveType != FUSLiveTypeAudience) {
return;
}
/// 仅付费屋场景展示
if (self.roomScopeType != FUSLiveRoomScopeTypePay) {
return;
}
UIView *rootView = [[FUSLiveHelper shareInstance].currentFunctionView fus_viewWithLayer:FUSLiveFunctionLayerFunctionButtons];
if (!rootView) {
return;
}
/// 如果接口未返回数据,也给一个空模型兜底,保证 UI 可展示
FUSPayRoomCompanionDataModel *dataModel = self.payRoomCompanionDataModel;
if (!dataModel) {
dataModel = [[FUSPayRoomCompanionDataModel alloc] init];
}
FUSPayRoomCompanionPopView *popView = [FUSPayRoomCompanionPopView fus_showWithRootView:rootView companionData:dataModel];
popView.unitPricePerMinute = self.payRoomUnitPricePerMinute;
popView.billingTimeMinutes = self.payRoomBillingTimeMinutes;
__weak typeof(self) weakSelf = self;
popView.rechargeHandler = ^{
/// 去充值:复用全局充值页入口
UIViewController *topVC = [UIViewController fus_topViewController];
if (topVC) {
[FUSRechargeViewController fus_showRechargeViewControllerForRootVC:topVC];
}
weakSelf.payRoomCompanionDataModel = nil;
};
}
/**
将直播间切换为“试看播放态”:
- 使用 preview 接口返回的 pullUrl 播放
......@@ -1834,6 +1890,9 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
[FUSLiveHelper shareInstance].roomInfoModel = roomInfoModel;
}
[[FUSLiveHelper shareInstance].liveVC.liveFunctionView fus_setupWithRoomInfoModel:roomInfoModel];
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf fus_showPayRoomCompanionPopIfNeededWithRoomId:roomInfoModel.roomId];
});
[FUSSocketMessageHelper fus_socketRoomConnectWithRoomId:roomInfoModel.roomId];
// [[FUSLiveGiftView shareGiftView] fus_requestGiftDataWithType:ReadDatabaseBegin success:nil failure:nil];
......
#import <FUSFoundation/FUSFoundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface FUSPayRoomCompanionDataModel : FUSBaseModel
/// 已陪伴时长(单位:分钟)
@property (nonatomic, assign) NSInteger companionTime;
/// 当前可继续陪伴时长(单位:分钟)
@property (nonatomic, assign) NSInteger canCompanionTime;
/// 是否时长充足(服务端语义:0 表示不足,需要引导充值;非 0 表示充足)
@property (nonatomic, assign) NSInteger isEnough;
@end
NS_ASSUME_NONNULL_END
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class FUSPayRoomCompanionDataModel;
@interface FUSPayRoomCompanionPopView : UIView
/// 点击“去充值”的回调(由外部决定跳转逻辑)
@property (nonatomic, copy, nullable) void (^rechargeHandler)(void);
@property (nonatomic, assign) NSInteger unitPricePerMinute;
@property (nonatomic, assign) NSInteger billingTimeMinutes;
/// 展示弹窗(如果已存在同类弹窗则复用并刷新数据)
+ (FUSPayRoomCompanionPopView *)fus_showWithRootView:(UIView *)rootView
companionData:(FUSPayRoomCompanionDataModel *)companionData;
/// 刷新展示内容(已陪伴/可继续陪伴/是否不足提示/进度条)
- (void)fus_updateWithCompanionData:(FUSPayRoomCompanionDataModel *)companionData;
@end
NS_ASSUME_NONNULL_END
#import "FUSPayRoomCompanionPopView.h"
#import <FUSFoundation/FUSFoundation.h>
#import <FUSCommon/FUSCommon.h>
#import "FUSPayRoomCompanionDataModel.h"
#import "FUSShowRoomCenterBunble.h"
#import "FUSPayRoomCompanionProgressView.h"
@interface FUSPayRoomCompanionPopView ()
/// 弹窗主要内容承载视图(圆角 + 毛玻璃背景的容器)
@property (nonatomic, strong) UIView *contentView;
/// 毛玻璃背景(覆盖在 contentView 上)
@property (nonatomic, strong) UIVisualEffectView *blurView;
/// “已陪伴:xx 分钟”文案
@property (nonatomic, strong) UILabel *companionLabel;
/// “下次计费”标题文案
@property (nonatomic, strong) UILabel *nextBillingLabel;
/// “您可继续陪伴 xx 分钟”文案
@property (nonatomic, strong) UILabel *continueLabel;
/// 宝石图标
@property (nonatomic, strong) UIImageView *diamondIconView;
/// 价格文案(如 “20/分钟”)
@property (nonatomic, strong) UILabel *priceLabel;
/// 预留:箭头按钮容器(当前未使用)
@property (nonatomic, strong) UIView *arrowContainerView;
/// 收起/展开按钮(左/右箭头两张图切换)
@property (nonatomic, strong) UIButton *arrowBtn;
/// 时长不足提示(isEnough=0 显示)
@property (nonatomic, strong) UILabel *tipLabel;
/// 计费进度条(含 thumb 指示点)
@property (nonatomic, strong) FUSPayRoomCompanionProgressView *progressView;
/// “储值”按钮(isEnough=0 显示)
@property (nonatomic, strong) UIButton *rechargeBtn;
/// 收起态的整块点击遮罩(用于点击任意位置展开)
@property (nonatomic, strong) UIButton *coverBtn;
/// 展开态目标高度(收起/展开动画的高度恢复用)
@property (nonatomic, assign) CGFloat originalHeight;
/// 内容左右内边距
@property (nonatomic, assign) CGFloat contentPadding;
/// 展开态时 progressView 原始 frame(收起/展开切换时恢复用)
@property (nonatomic, assign) CGRect expandedProgressFrame;
/// 正常状态高度(无“储值”按钮)
@property (nonatomic, assign) CGFloat normalHeight;
/// 不足状态高度(含“储值”按钮)
@property (nonatomic, assign) CGFloat rechargeHeight;
/// 最近一次刷新用的数据(用于展开后复原显示)
@property (nonatomic, strong) FUSPayRoomCompanionDataModel *lastCompanionData;
/// 第一条虚线分割(“已陪伴”下方)
@property (nonatomic, strong) CAShapeLayer *dashLine1Layer;
/// 第二条虚线分割(“可继续陪伴”上方)
@property (nonatomic, strong) CAShapeLayer *dashLine2Layer;
@end
@implementation FUSPayRoomCompanionPopView
+ (FUSPayRoomCompanionPopView *)fus_showWithRootView:(UIView *)rootView
companionData:(FUSPayRoomCompanionDataModel *)companionData
{
if (!rootView) {
return nil;
}
UIView *existView = [rootView viewWithTag:90917001];
if ([existView isKindOfClass:FUSPayRoomCompanionPopView.class]) {
[existView removeFromSuperview];
}
CGFloat viewW = 120;
CGFloat viewH = (companionData.isEnough == 0 ? 160 : 123);
CGFloat viewX = 10;
CGFloat viewY = UIView.fus_SafeTop + 205;
FUSPayRoomCompanionPopView *popView = [[FUSPayRoomCompanionPopView alloc] initWithFrame:CGRectMake(viewX, viewY, viewW, viewH)];
popView.tag = 90917001;
[rootView addSubview:popView];
[popView fus_updateWithCompanionData:companionData];
return popView;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = UIColor.clearColor;
self.clipsToBounds = NO;
self.normalHeight = 123;
CGFloat arrowW = 14;
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width - arrowW, self.height)];
self.contentView.layer.cornerRadius = 8;
self.contentView.layer.masksToBounds = YES;
[self addSubview:self.contentView];
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
self.blurView = [[UIVisualEffectView alloc] initWithEffect:effect];
self.blurView.frame = self.contentView.bounds;
self.blurView.alpha = 0.85;
[self.contentView addSubview:self.blurView];
self.arrowBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.arrowBtn.frame = CGRectMake(self.contentView.width, 0, 14, 17);
self.arrowBtn.centerY = 16.5;
[self.arrowBtn setImage:[FUSShowRoomCenterBunble imageNamed:@"live_anchor_reward_arrow_left"] forState:UIControlStateNormal];
[self.arrowBtn setImage:[FUSShowRoomCenterBunble imageNamed:@"live_anchor_reward_arrow_right"] forState:UIControlStateSelected];
[self.arrowBtn addTarget:self action:@selector(fus_clickArrowBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.arrowBtn];
self.contentPadding = 9;
CGFloat contentPadding = self.contentPadding;
CGFloat contentW = self.contentView.width - contentPadding * 2;
CGFloat y = 8;
self.companionLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPadding, y, contentW, 14)];
self.companionLabel.font = [UIFont boldSystemFontOfSize:9];
self.companionLabel.textColor = [UIColor colorWithWhite:1 alpha:0.95];
[self.contentView addSubview:self.companionLabel];
y = self.companionLabel.bottom + 6;
self.dashLine1Layer = [CAShapeLayer layer];
self.dashLine1Layer.strokeColor = [UIColor colorWithWhite:1 alpha:0.35].CGColor;
self.dashLine1Layer.fillColor = UIColor.clearColor.CGColor;
self.dashLine1Layer.lineWidth = 1;
self.dashLine1Layer.lineDashPattern = @[@3, @3];
[self.contentView.layer addSublayer:self.dashLine1Layer];
self.dashLine1Layer.path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 0, 0)].CGPath;
y = y + 8;
self.nextBillingLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPadding, y, contentW, 12)];
self.nextBillingLabel.font = [UIFont fus_themeFont:8];
self.nextBillingLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9];
self.nextBillingLabel.text = [NSString fus_localString:@"下次计费"];
[self.contentView addSubview:self.nextBillingLabel];
CGFloat progressH = 6;
self.progressView = [[FUSPayRoomCompanionProgressView alloc] initWithFrame:CGRectMake(contentPadding, self.nextBillingLabel.bottom + 4, contentW, progressH)];
[self.contentView addSubview:self.progressView];
y = self.progressView.bottom + 6;
self.tipLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPadding, y, contentW, 10)];
self.tipLabel.font = [UIFont fus_themeFont:8];
self.tipLabel.textColor = [UIColor colorWithRed:(255.0 / 255.0) green:(86.0 / 255.0) blue:(86.0 / 255.0) alpha:1.0];
self.tipLabel.text = [NSString fus_localString:@"时长不足,建议充值"];
self.tipLabel.hidden = YES;
[self.contentView addSubview:self.tipLabel];
self.dashLine2Layer = [CAShapeLayer layer];
self.dashLine2Layer.strokeColor = [UIColor colorWithWhite:1 alpha:0.22].CGColor;
self.dashLine2Layer.fillColor = UIColor.clearColor.CGColor;
self.dashLine2Layer.lineWidth = 1;
self.dashLine2Layer.lineDashPattern = @[@3, @3];
[self.contentView.layer addSublayer:self.dashLine2Layer];
self.dashLine2Layer.path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 0, 0)].CGPath;
y = self.tipLabel.bottom + 10;
self.continueLabel = [[UILabel alloc] initWithFrame:CGRectMake(contentPadding, y, contentW, 12)];
self.continueLabel.font = [UIFont fus_themeFont:8];
self.continueLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9];
[self.contentView addSubview:self.continueLabel];
y = self.continueLabel.bottom + 6;
CGFloat iconSize = 10;
self.diamondIconView = [[UIImageView alloc] initWithFrame:CGRectMake(contentPadding, y + 1, iconSize, iconSize)];
self.diamondIconView.contentMode = UIViewContentModeScaleAspectFit;
self.diamondIconView.image = UIImage.fus_diamonIcon;
[self.contentView addSubview:self.diamondIconView];
CGFloat priceX = self.diamondIconView.right + 6;
CGFloat priceW = MAX(0, self.contentView.width - contentPadding - priceX);
self.priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(priceX, y - 1, priceW, 12)];
self.priceLabel.font = [UIFont boldSystemFontOfSize:8];
self.priceLabel.textColor = [UIColor fus_diamondBlue];
self.priceLabel.text = @"0/分钟";
[self.contentView addSubview:self.priceLabel];
self.rechargeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
CGFloat btnTop = self.diamondIconView.bottom + 8;
CGFloat btnH = 28;
self.rechargeBtn.frame = CGRectMake(contentPadding, btnTop, contentW, btnH);
self.rechargeBtn.layer.cornerRadius = btnH / 2.0;
self.rechargeBtn.layer.masksToBounds = YES;
self.rechargeBtn.backgroundColor = [UIColor colorWithHex:@"#00F7FF"];
self.rechargeBtn.titleLabel.font = [UIFont boldSystemFontOfSize:12];
[self.rechargeBtn setTitle:[NSString fus_localString:@"储值"] forState:UIControlStateNormal];
[self.rechargeBtn setTitleColor:[UIColor colorWithHex:@"#111111"] forState:UIControlStateNormal];
[self.rechargeBtn addTarget:self action:@selector(fus_clickRecharge) forControlEvents:UIControlEventTouchUpInside];
self.rechargeBtn.hidden = YES;
[self.contentView addSubview:self.rechargeBtn];
CGFloat requiredHeight = CGRectGetMaxY(self.rechargeBtn.frame) + contentPadding;
self.rechargeHeight = MAX(self.normalHeight, requiredHeight);
if (self.height < self.rechargeHeight) {
self.height = self.rechargeHeight;
self.contentView.height = self.rechargeHeight;
self.blurView.frame = self.contentView.bounds;
}
self.originalHeight = self.height;
self.expandedProgressFrame = self.progressView.frame;
self.coverBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.coverBtn.frame = self.bounds;
self.coverBtn.hidden = YES;
[self.coverBtn addTarget:self action:@selector(fus_clickArrowBtnAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.coverBtn];
}
return self;
}
- (void)fus_updateWithCompanionData:(FUSPayRoomCompanionDataModel *)companionData {
self.lastCompanionData = companionData;
NSInteger companionTime = companionData.companionTime;
NSInteger canCompanionTime = companionData.canCompanionTime;
NSInteger totalTime = MAX(0, companionTime) + MAX(0, canCompanionTime);
self.companionLabel.text = [NSString stringWithFormat:[NSString fus_localString:@"已陪伴:%ld 分钟"], (long)MAX(0, companionTime)];
self.continueLabel.text = [NSString stringWithFormat:[NSString fus_localString:@"您可继续陪伴 %ld 分钟"], (long)MAX(0, canCompanionTime)];
self.tipLabel.hidden = (companionData.isEnough != 0);
self.rechargeBtn.hidden = (companionData.isEnough != 0);
CGFloat targetHeight = (companionData.isEnough == 0 ? self.rechargeHeight : self.normalHeight);
self.originalHeight = targetHeight;
if (self.arrowBtn.isSelected == NO && CGAffineTransformIsIdentity(self.transform)) {
self.height = targetHeight;
self.contentView.height = targetHeight;
self.blurView.frame = self.contentView.bounds;
self.coverBtn.frame = self.bounds;
}
NSInteger unitPrice = MAX(0, self.unitPricePerMinute);
NSString *priceText = [NSString stringWithFormat:@"%ld /%@", (long)unitPrice,[NSString fus_localString:@"分钟"]];
NSMutableAttributedString *priceAttr = [[NSMutableAttributedString alloc] initWithString:priceText attributes:@{
NSFontAttributeName: self.priceLabel.font ?: [UIFont boldSystemFontOfSize:8],
NSForegroundColorAttributeName: [UIColor colorWithWhite:1 alpha:0.9]
}];
NSRange slashRange = [priceText rangeOfString:@"/"];
if (slashRange.location != NSNotFound && slashRange.location > 0) {
[priceAttr addAttribute:NSForegroundColorAttributeName value:[UIColor fus_diamondBlue] range:NSMakeRange(0, slashRange.location)];
} else {
[priceAttr addAttribute:NSForegroundColorAttributeName value:[UIColor fus_diamondBlue] range:NSMakeRange(0, priceText.length)];
}
self.priceLabel.attributedText = priceAttr;
CGFloat progress = 0;
NSInteger billingTime = MAX(0, self.billingTimeMinutes);
if (billingTime > 0) {
NSInteger usedInCycle = (NSInteger)(MAX(0, companionTime) % billingTime);
progress = (CGFloat)usedInCycle / (CGFloat)billingTime;
} else if (totalTime > 0) {
progress = (CGFloat)MAX(0, companionTime) / (CGFloat)totalTime;
} else {
progress = 0.7;
}
[self.progressView fus_setProgress:progress animated:YES];
CGFloat dashLeft = 16;
CGFloat dashRight = self.contentView.width - 16;
CGFloat y1 = CGRectGetMaxY(self.companionLabel.frame) + 6;
UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 moveToPoint:CGPointMake(dashLeft, y1)];
[path1 addLineToPoint:CGPointMake(dashRight, y1)];
self.dashLine1Layer.path = path1.CGPath;
CGFloat y2 = CGRectGetMinY(self.continueLabel.frame) - 6;
UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(dashLeft, y2)];
[path2 addLineToPoint:CGPointMake(dashRight, y2)];
self.dashLine2Layer.path = path2.CGPath;
}
- (void)fus_clickArrowBtnAction:(UIButton *)sender {
self.userInteractionEnabled = NO;
if (self.arrowBtn.isSelected == NO) {
self.arrowBtn.selected = YES;
self.companionLabel.hidden = YES;
self.nextBillingLabel.hidden = YES;
self.tipLabel.hidden = YES;
self.continueLabel.hidden = YES;
self.diamondIconView.hidden = YES;
self.priceLabel.hidden = YES;
self.rechargeBtn.hidden = YES;
self.dashLine1Layer.hidden = YES;
self.dashLine2Layer.hidden = YES;
CGFloat collapsedH = 33;
CGFloat progressH = self.progressView.height;
CGFloat progressY = (collapsedH - progressH) / 2.0;
CGFloat progressW = self.contentView.width - self.contentPadding * 2;
self.progressView.frame = CGRectMake(self.contentPadding, progressY, progressW, progressH);
CGFloat scaleFactor = 0.617;
CGSize originalSize = self.size;
[UIView animateWithDuration:0.3 animations:^{
self.height = collapsedH;
self.transform = CGAffineTransformTranslate(CGAffineTransformScale(CGAffineTransformIdentity, scaleFactor, scaleFactor), -originalSize.width * scaleFactor / 2, -collapsedH * scaleFactor / 2);
self.contentView.height = collapsedH;
self.blurView.frame = self.contentView.bounds;
self.contentView.layer.cornerRadius = 5;
self.contentView.layer.masksToBounds = YES;
} completion:^(BOOL finished) {
self.userInteractionEnabled = YES;
self.coverBtn.hidden = NO;
self.coverBtn.frame = self.bounds;
}];
} else {
[self.layer removeAllAnimations];
self.arrowBtn.selected = NO;
[UIView animateWithDuration:0.3 animations:^{
self.transform = CGAffineTransformIdentity;
self.height = self.originalHeight;
self.contentView.height = self.originalHeight;
self.blurView.frame = self.contentView.bounds;
self.contentView.layer.cornerRadius = 8;
self.contentView.layer.masksToBounds = YES;
} completion:^(BOOL finished) {
self.userInteractionEnabled = YES;
self.coverBtn.hidden = YES;
self.coverBtn.frame = self.bounds;
self.progressView.frame = self.expandedProgressFrame;
self.companionLabel.hidden = NO;
self.nextBillingLabel.hidden = NO;
self.continueLabel.hidden = NO;
self.diamondIconView.hidden = NO;
self.priceLabel.hidden = NO;
self.dashLine1Layer.hidden = NO;
self.dashLine2Layer.hidden = NO;
if (self.lastCompanionData) {
[self fus_updateWithCompanionData:self.lastCompanionData];
}
}];
}
}
- (void)fus_clickRecharge {
if (self.rechargeHandler) {
self.rechargeHandler();
}
[self fus_dismissView];
}
- (void)fus_dismissView {
[self removeFromSuperview];
}
@end
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FUSPayRoomCompanionProgressView : UIView
/// 进度值范围 0~1;超出范围会被内部裁剪
@property (nonatomic, assign) CGFloat progress;
/// 轨道(背景)图片;若设置,会按圆角进度条样式做可拉伸处理以避免变形
@property (nonatomic, strong, nullable) UIImage *trackImage;
/// 填充(前景)图片;为 nil 时使用默认填充色
@property (nonatomic, strong, nullable) UIImage *fillImage;
/// 进度指示点图片;为 nil 时使用默认圆点样式
@property (nonatomic, strong, nullable) UIImage *thumbImage;
/// 设置进度(0~1);animated=YES 时使用短动画平滑过渡
- (void)fus_setProgress:(CGFloat)progress animated:(BOOL)animated;
@end
NS_ASSUME_NONNULL_END
#import "FUSPayRoomCompanionProgressView.h"
@interface FUSPayRoomCompanionProgressView ()
@property (nonatomic, strong) UIImageView *trackImageView;
@property (nonatomic, strong) UIImageView *fillImageView;
@property (nonatomic, strong) UIImageView *thumbImageView;
@end
@implementation FUSPayRoomCompanionProgressView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = UIColor.clearColor;
self.clipsToBounds = NO;
self.trackImageView = [[UIImageView alloc] initWithFrame:self.bounds];
self.trackImageView.contentMode = UIViewContentModeScaleToFill;
self.trackImageView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.35];
self.trackImageView.layer.cornerRadius = self.bounds.size.height / 2.0;
self.trackImageView.layer.masksToBounds = YES;
[self addSubview:self.trackImageView];
self.fillImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, self.bounds.size.height)];
self.fillImageView.contentMode = UIViewContentModeScaleToFill;
self.fillImageView.backgroundColor = [UIColor colorWithHex:@"#00F7FF"];
self.fillImageView.layer.cornerRadius = self.bounds.size.height / 2.0;
self.fillImageView.layer.masksToBounds = YES;
[self addSubview:self.fillImageView];
self.thumbImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 18, 18)];
self.thumbImageView.image = [FUSShowRoomCenterBunble imageNamed:@"live_anchor_progress"];
self.thumbImageView.contentMode = UIViewContentModeScaleAspectFit;
self.thumbImageView.backgroundColor = UIColor.clearColor;
self.thumbImageView.layer.cornerRadius = 9;
self.thumbImageView.layer.masksToBounds = YES;
[self addSubview:self.thumbImageView];
[self fus_setProgress:0 animated:NO];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.trackImageView.frame = self.bounds;
self.trackImageView.layer.cornerRadius = self.bounds.size.height / 2.0;
CGFloat progress = MIN(1, MAX(0, self.progress));
CGFloat fillW = self.bounds.size.width * progress;
self.fillImageView.frame = CGRectMake(0, 0, fillW, self.bounds.size.height);
self.fillImageView.layer.cornerRadius = self.bounds.size.height / 2.0;
CGFloat thumbX = fillW;
thumbX = MIN(self.bounds.size.width, MAX(0, thumbX));
self.thumbImageView.center = CGPointMake(thumbX, self.bounds.size.height / 2.0);
}
- (void)setTrackImage:(UIImage *)trackImage
{
_trackImage = trackImage;
UIImage *finalTrackImage = trackImage;
if (finalTrackImage) {
CGFloat cap = floor(finalTrackImage.size.height / 2.0);
cap = MAX(1, cap);
finalTrackImage = [finalTrackImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, cap, 0, cap) resizingMode:UIImageResizingModeStretch];
}
self.trackImageView.image = finalTrackImage;
self.trackImageView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.35];
}
- (void)setFillImage:(UIImage *)fillImage
{
_fillImage = fillImage;
self.fillImageView.image = fillImage;
self.fillImageView.backgroundColor = fillImage ? UIColor.clearColor : [UIColor colorWithHex:@"#00F7FF"];
}
- (void)setThumbImage:(UIImage *)thumbImage
{
_thumbImage = thumbImage;
self.thumbImageView.image = thumbImage;
self.thumbImageView.layer.masksToBounds = (thumbImage == nil);
self.thumbImageView.backgroundColor = thumbImage ? UIColor.clearColor : [UIColor colorWithWhite:1 alpha:0.9];
}
- (void)fus_setProgress:(CGFloat)progress animated:(BOOL)animated
{
_progress = MIN(1, MAX(0, progress));
if (!animated) {
[self setNeedsLayout];
[self layoutIfNeeded];
return;
}
[UIView animateWithDuration:0.2 animations:^{
[self setNeedsLayout];
[self layoutIfNeeded];
}];
}
@end
......@@ -92,7 +92,7 @@
CGFloat viewW = 120;
CGFloat viewH = 123;
CGFloat viewY = UIView.fus_SafeTop + 135;
CGFloat viewY = UIView.fus_SafeTop + 205;
FusAnchorPayRoomView *payRoomView = [[FusAnchorPayRoomView alloc] initWithFrame:CGRectMake(10, viewY, viewW, viewH)];
payRoomView.originalHeight = payRoomView.height;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment