同步商城修改

This commit is contained in:
zjx 2025-06-18 09:40:55 +08:00
parent e9c2b300d6
commit 348d4c869c
64 changed files with 1232 additions and 77 deletions

View File

@ -162,6 +162,12 @@
BFCCE13D2DFFFAC500EDE165 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */; };
BFCCE1402E000ACE00EDE165 /* VPAnpsAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */; };
BFCCE1422E000F4800EDE165 /* VPHomePlayHistoricalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.swift */; };
BFA21D982E01477200B3573D /* VPStoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D972E01477200B3573D /* VPStoreViewController.swift */; };
BFA21D9A2E01497F00B3573D /* VPStoreVipBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */; };
BFA21D9C2E01628F00B3573D /* VPStoreCoinsBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */; };
BFA21D9E2E01684E00B3573D /* VPStoreCoinsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */; };
BFA21DA02E01688D00B3573D /* VPStoreCoinsBigItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */; };
BFA21DA22E01696700B3573D /* VPStoreCoinsSmallItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */; };
BFF5AFA42DE6F15E0044227A /* VPMeVipCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */; };
BFF5AFA62DE700420044227A /* VPMeVipPrivilegeItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */; };
BFF5AFA82DE704DC0044227A /* VPMeCoinCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */; };
@ -427,6 +433,12 @@
BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPAnpsAlertView.swift; sourceTree = "<group>"; };
BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPHomePlayHistoricalView.swift; sourceTree = "<group>"; };
BFA21D972E01477200B3573D /* VPStoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreViewController.swift; sourceTree = "<group>"; };
BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreVipBuyView.swift; sourceTree = "<group>"; };
BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBuyView.swift; sourceTree = "<group>"; };
BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsItemView.swift; sourceTree = "<group>"; };
BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBigItemView.swift; sourceTree = "<group>"; };
BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsSmallItemView.swift; sourceTree = "<group>"; };
BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipCell.swift; sourceTree = "<group>"; };
BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipPrivilegeItemView.swift; sourceTree = "<group>"; };
BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCoinCell.swift; sourceTree = "<group>"; };
@ -1208,6 +1220,7 @@
BFF5AFBC2DE837790044227A /* Controller */ = {
isa = PBXGroup;
children = (
BFA21D972E01477200B3573D /* VPStoreViewController.swift */,
BFF5AFAD2DE717BB0044227A /* VPVipPageViewController.swift */,
BFF5AFAF2DE7F9A80044227A /* VPVipViewController.swift */,
BFF5AFB32DE7FF4E0044227A /* VPCoinsViewController.swift */,
@ -1234,6 +1247,11 @@
BFF5AFD32DE9A5FB0044227A /* VPVIPRecordCell.swift */,
BFF5B2512DF130E00044227A /* VPConsumptionRecordsCell.swift */,
BFF5B2592DF13BE50044227A /* VPGiveCoinRecordsCell.swift */,
BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */,
BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */,
BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */,
BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */,
BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */,
);
path = View;
sourceTree = "<group>";
@ -1500,6 +1518,7 @@
BF0FA78B2DE164C100C9E5F2 /* VPSearchResultCell.swift in Sources */,
BF0FA71D2DDC807200C9E5F2 /* UIImageView+VPAdd.swift in Sources */,
BFF5B22C2DEFE8A80044227A /* VPDeleteAccountViewController.swift in Sources */,
BFA21D9E2E01684E00B3573D /* VPStoreCoinsItemView.swift in Sources */,
BF0FA6DC2DDC5CD700C9E5F2 /* VPTokenModel.swift in Sources */,
BF0FA7572DDF159B00C9E5F2 /* VPExploreViewController.swift in Sources */,
1B056E772DDB3641007EE38D /* VPTabBarItemNormalVew.swift in Sources */,
@ -1603,11 +1622,13 @@
BFF5AFC82DE9473B0044227A /* VPCoinsBuyCell.swift in Sources */,
BF0FA72C2DDD7B7300C9E5F2 /* VPHomeRankingContentCell.swift in Sources */,
BF0FA7AF2DE443E000C9E5F2 /* VPMeViewController.swift in Sources */,
BFA21DA02E01688D00B3573D /* VPStoreCoinsBigItemView.swift in Sources */,
BF0FA7942DE16E9300C9E5F2 /* JXTagView.swift in Sources */,
BF0FA7A52DE4384100C9E5F2 /* AttributedString+VPAdd.swift in Sources */,
BF0FA7652DE00A0E00C9E5F2 /* VPDetailPlayerControlView.swift in Sources */,
BF0FA7342DDEC74500C9E5F2 /* VPCategoryModel.swift in Sources */,
BFF5B2322DEFF1220044227A /* VPDeleteAccountDetailView.swift in Sources */,
BFA21D9A2E01497F00B3573D /* VPStoreVipBuyView.swift in Sources */,
1B056E4F2DDAC7FC007EE38D /* VPNavigationController.swift in Sources */,
1B056E3F2DDAC2DB007EE38D /* VPCryptorService.swift in Sources */,
BF0FA7202DDC83AE00C9E5F2 /* JXButton.swift in Sources */,
@ -1638,6 +1659,7 @@
BF0FA7022DDC667C00C9E5F2 /* VPVideoInfoModel.swift in Sources */,
BF0FA77B2DE0788A00C9E5F2 /* UIStackView+VPAdd.swift in Sources */,
BF0FA7BE2DE4592A00C9E5F2 /* UserDefaults+VPAdd.swift in Sources */,
BFA21DA22E01696700B3573D /* VPStoreCoinsSmallItemView.swift in Sources */,
BFF5B2232DEEF8DA0044227A /* VPLoginButton.swift in Sources */,
BF0FA76F2DE062A700C9E5F2 /* VPRateSelectedView.swift in Sources */,
BF0FA7772DE0735800C9E5F2 /* VPSearchInputView.swift in Sources */,
@ -1654,6 +1676,7 @@
BFF5B2392DF014520044227A /* VPBaseAlertView.swift in Sources */,
BFF5AFCC2DE98C7F0044227A /* VPOrderRecordsViewController.swift in Sources */,
1B056E412DDAC30A007EE38D /* VPModel.swift in Sources */,
BFA21D982E01477200B3573D /* VPStoreViewController.swift in Sources */,
BF0FA70A2DDC69C800C9E5F2 /* VPTableViewCell.swift in Sources */,
BFF5B2752DF2C3750044227A /* VPDetailRecommandView.swift in Sources */,
BF0FA7A12DE1AA5100C9E5F2 /* VPTableView.swift in Sources */,
@ -1688,6 +1711,7 @@
BF0FA7B62DE44E8000C9E5F2 /* VPWebView.swift in Sources */,
1B056E492DDAC3DF007EE38D /* VPAppTool.swift in Sources */,
BFF5AFE62DEEDB7F0044227A /* VPRewardsViewController.swift in Sources */,
BFA21D9C2E01628F00B3573D /* VPStoreCoinsBuyView.swift in Sources */,
BF0FA74E2DDF067E00C9E5F2 /* VPVideoPlayViewModel.swift in Sources */,
BFF5B24A2DF0524D0044227A /* AppDelegate+Open.swift in Sources */,
BFF5B2412DF045BF0044227A /* VPRewardsAPI.swift in Sources */,
@ -1763,7 +1787,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.3;
PRODUCT_BUNDLE_IDENTIFIER = com.qjwl168.veloria.ios;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1804,7 +1828,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
MARKETING_VERSION = 1.0.3;
PRODUCT_BUNDLE_IDENTIFIER = com.qjwl168.veloria.ios;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -254,4 +254,83 @@ extension UIColor {
return UIColor(rgb: 0xDBDBDB, alpha: alpha)
}
static func color7869FF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x7869FF, alpha: alpha)
}
static func color9F45FF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x9F45FF, alpha: alpha)
}
static func colorBDFFFB(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xBDFFFB, alpha: alpha)
}
static func color7AD9D4(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x7AD9D4, alpha: alpha)
}
static func colorADCFFF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xADCFFF, alpha: alpha)
}
static func color7CA1D7(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x7CA1D7, alpha: alpha)
}
static func colorDBC7FF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xDBC7FF, alpha: alpha)
}
static func color975DFF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x975DFF, alpha: alpha)
}
static func color16706A(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x16706A, alpha: alpha)
}
static func color214170(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x214170, alpha: alpha)
}
static func color510087(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x510087, alpha: alpha)
}
static func color683D00(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x683D00, alpha: alpha)
}
static func color5F1EB9(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x5F1EB9, alpha: alpha)
}
static func colorCABCFF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xCABCFF, alpha: alpha)
}
static func color8790B7(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x8790B7, alpha: alpha)
}
static func color8AAEA6(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x8AAEA6, alpha: alpha)
}
static func colorA395D9(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xA395D9, alpha: alpha)
}
static func colorAC978D(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xAC978D, alpha: alpha)
}
static func colorFFC779(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xFFC779, alpha: alpha)
}
static func colorFF9500(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xFF9500, alpha: alpha)
}
}

View File

@ -74,7 +74,7 @@ extension VPMeToolCell {
}
@objc private func handleStoreButton() {
let vc = VPVipPageViewController()
let vc = VPStoreViewController()
self.viewController?.navigationController?.pushViewController(vc, animated: true)
}

View File

@ -104,7 +104,7 @@ class VPMeVipCell: VPTableViewCell {
}
@objc private func handleBgView() {
let vc = VPVipPageViewController()
let vc = VPStoreViewController()
self.viewController?.navigationController?.pushViewController(vc, animated: true)
}

View File

@ -12,13 +12,13 @@ class VPPlayerRechargeView: HWPanModalContentView {
var shortPlayId: String? {
didSet {
vipView.shortPlayId = shortPlayId
coinView.shortPlayId = shortPlayId
coinsView.shortPlayId = shortPlayId
}
}
var videoId: String? {
didSet {
vipView.videoId = videoId
coinView.videoId = videoId
coinsView.videoId = videoId
}
}
@ -56,13 +56,13 @@ class VPPlayerRechargeView: HWPanModalContentView {
private lazy var stackView: UIStackView = {
let view = UIStackView()
view.axis = .vertical
view.spacing = 0
view.alignment = .center
view.spacing = 12
return view
}()
private lazy var vipView: VPPlayerVipBuyView = {
let view = VPPlayerVipBuyView()
private lazy var vipView: VPStoreVipBuyView = {
let view = VPStoreVipBuyView()
view.buyFinishBlock = { [weak self] in
self?.buyFinishBlock?()
self?.dismiss(animated: true) {
@ -71,8 +71,8 @@ class VPPlayerRechargeView: HWPanModalContentView {
return view
}()
private lazy var coinView: VPPlayerCoinBuyView = {
let view = VPPlayerCoinBuyView()
private lazy var coinsView: VPStoreCoinsBuyView = {
let view = VPStoreCoinsBuyView()
view.buyFinishBlock = { [weak self] in
self?.buyFinishBlock?()
self?.dismiss(animated: true) {
@ -81,6 +81,38 @@ class VPPlayerRechargeView: HWPanModalContentView {
return view
}()
// private lazy var vipView: VPPlayerVipBuyView = {
// let view = VPPlayerVipBuyView()
// view.buyFinishBlock = { [weak self] in
// self?.buyFinishBlock?()
// self?.dismiss(animated: true) {
// }
// }
// return view
// }()
//
// private lazy var coinView: VPPlayerCoinBuyView = {
// let view = VPPlayerCoinBuyView()
// view.buyFinishBlock = { [weak self] in
// self?.buyFinishBlock?()
// self?.dismiss(animated: true) {
// }
// }
// return view
// }()
private lazy var tipView: UIView = {
let view = UIView()
view.addSubview(tipLabel)
tipLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.lessThanOrEqualToSuperview().offset(-15)
make.top.bottom.equalToSuperview()
}
return view
}()
private lazy var tipLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
@ -126,7 +158,8 @@ class VPPlayerRechargeView: HWPanModalContentView {
}
override func longFormHeight() -> PanModalHeight {
return PanModalHeightMake(.content, UIScreen.height * (2 / 3))
// return PanModalHeightMake(.content, UIScreen.height * (4 / 5))
return PanModalHeightMake(.content, UIScreen.height - UIScreen.navBarHeight - 20)
}
override func showDragIndicator() -> Bool {
@ -211,12 +244,12 @@ extension VPPlayerRechargeView {
coinIconImageView.snp.makeConstraints { make in
make.left.equalTo(coinLabel.snp.right).offset(3)
make.top.equalToSuperview().offset(40)
make.centerY.equalTo(closeButton)
}
scrollView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
make.top.equalToSuperview().offset(56)
make.top.equalToSuperview().offset(41)
make.bottom.equalToSuperview()
}
@ -239,24 +272,35 @@ extension VPPlayerRechargeView {
stackView.removeAllArrangedSubview()
if let model = model {
self.vipView.dataArr = model.list_sub_vip ?? []
self.coinView.dataArr = model.list_coins ?? []
if self.vipView.dataArr.count > 0 {
if let list = model.list_sub_vip, list.count > 0 {
self.stackView.addArrangedSubview(self.vipView)
self.vipView.dataArr = list
}
if self.coinView.dataArr.count > 0 {
self.stackView.addArrangedSubview(self.coinView)
if let list = model.list_coins, list.count > 0 {
self.stackView.addArrangedSubview(self.coinsView)
self.coinsView.dataArr = list
}
if let view = self.stackView.arrangedSubviews.last {
self.stackView.setCustomSpacing(12, after: view)
if self.stackView.arrangedSubviews.count == 1,
let view = self.stackView.arrangedSubviews.first,
view == self.coinsView {
scrollView.snp.updateConstraints { make in
make.top.equalToSuperview().offset(56)
}
} else {
scrollView.snp.updateConstraints { make in
make.top.equalToSuperview().offset(41)
}
}
self.stackView.addArrangedSubview(tipLabel)
self.stackView.addArrangedSubview(tipView)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
self?.panModalSetNeedsLayoutUpdate()
}
self.panModalSetNeedsLayoutUpdate()
}
}

View File

@ -209,10 +209,10 @@ extension VPPlayerVipBuyView: ZKCycleScrollViewDelegate, ZKCycleScrollViewDataSo
cycleScrollView.reloadData()
}
VPIAPManager.manager.start(model: dataArr[index]) { finish in
VPIAPManager.manager.start(model: dataArr[index]) { [weak self] finish in
if finish {
VPLoginManager.manager.updateUserInfo(completer: nil)
self.buyFinishBlock?()
self?.buyFinishBlock?()
}
}
}

View File

@ -0,0 +1,130 @@
//
// VPStoreViewController.swift
// Veloria
//
// Created by on 2025/6/17.
//
import UIKit
class VPStoreViewController: VPViewController {
private lazy var scrollView: VPScrollView = {
let scrollView = VPScrollView()
return scrollView
}()
private lazy var stackView: UIStackView = {
let view = UIStackView()
view.spacing = 12
view.axis = .vertical
return view
}()
private lazy var vipView: VPStoreVipBuyView = {
let view = VPStoreVipBuyView()
return view
}()
private lazy var coinsView: VPStoreCoinsBuyView = {
let view = VPStoreCoinsBuyView()
return view
}()
private lazy var tipView: UIView = {
let view = UIView()
view.addSubview(tipLabel)
tipLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.lessThanOrEqualToSuperview().offset(-15)
make.top.bottom.equalToSuperview()
}
return view
}()
private lazy var tipLabel: UILabel = {
let label = UILabel()
label.textColor = .colorFFFFFF(alpha: 0.5)
label.font = .fontRegular(ofSize: 12)
label.numberOfLines = 0
label.text = "veloria_store_tips_ios".localized
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "veloria_store".localized
let rightBar = UIBarButtonItem(title: "Restore".localized, style: .plain, target: self, action: #selector(handleRestore))
self.navigationItem.rightBarButtonItem = rightBar
vp_setupUI()
requestData()
self.stackView.addArrangedSubview(self.tipView)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
self.setNavigationNormalStyle()
}
@objc private func handleRestore() {
VPIAPManager.manager.restore(isLoding: true) { isFinish in
if isFinish {
VPLoginManager.manager.updateUserInfo(completer: nil)
}
}
}
}
extension VPStoreViewController {
private func vp_setupUI() {
view.addSubview(scrollView)
scrollView.addSubview(stackView)
scrollView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
}
stackView.snp.makeConstraints { make in
make.left.centerX.equalToSuperview()
make.top.equalToSuperview()
make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 15))
}
}
}
extension VPStoreViewController {
private func requestData() {
VPWalletAPI.requestPayTemplate { [weak self] model in
guard let self = self else { return }
if let model = model {
self.stackView.removeAllArrangedSubview()
if let list = model.list_sub_vip, list.count > 0 {
self.stackView.addArrangedSubview(self.vipView)
self.vipView.dataArr = list
}
if let list = model.list_coins, list.count > 0 {
self.stackView.addArrangedSubview(self.coinsView)
self.coinsView.dataArr = list
}
self.stackView.addArrangedSubview(self.tipView)
}
}
}
}

View File

@ -33,6 +33,11 @@ class VPPayTemplateItem: VPModel, SmartCodable {
}
}
enum SizeType: String, SmartCaseDefaultable {
case big = "big"
case small = "small"
}
var id: String?
var status: String?
@ -54,6 +59,8 @@ class VPPayTemplateItem: VPModel, SmartCodable {
var send_coin_ttl: Int?
var size: SizeType?
var ios_template_id: String?

View File

@ -0,0 +1,55 @@
//
// VPStoreCoinsBigItemView.swift
// Veloria
//
// Created by on 2025/6/17.
//
import UIKit
class VPStoreCoinsBigItemView: VPStoreCoinsItemView {
override var intrinsicContentSize: CGSize {
let width = floor((UIScreen.width - 30 - 10) / 2)
return .init(width: width, height: 108)
}
override var item: VPPayTemplateItem? {
didSet {
if let mark = item?.corner_marker, !mark.isEmpty {
hotImageView.isHidden = false
} else {
hotImageView.isHidden = true
}
}
}
private lazy var hotImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "hot_icon_04"))
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
bgView.image = UIImage(named: "coin_big_bg_image")
bonusLabel.textColor = .colorFFC779()
bottomView.colors = [UIColor.colorFBF2C7(alpha: 0.9).cgColor, UIColor.colorA87A46(alpha: 0.9).cgColor]
priceLabel.font = .fontMedium(ofSize: 14)
priceLabel.textColor = .color683D00()
bonusRatioView.backgroundColor = .colorFF9500()
selectedImageView.image = UIImage(named: "selected_icon_02")
bgView.addSubview(hotImageView)
hotImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(4)
make.top.equalToSuperview().offset(3)
}
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -0,0 +1,258 @@
//
// VPStoreCoinsBuyView.swift
// Veloria
//
// Created by on 2025/6/17.
//
import UIKit
class VPStoreCoinsBuyView: UIView {
var buyFinishBlock: (() -> Void)?
var shortPlayId: String?
var videoId: String?
var dataArr: [VPPayTemplateItem] = [] {
didSet {
selectedItem = nil
bigDataArr.removeAll()
smallDataArr.removeAll()
dataArr.forEach {
if $0.size == .big {
bigDataArr.append($0)
} else {
smallDataArr.append($0)
}
}
CATransaction.setCompletionBlock { [weak self] in
guard let self = self else { return }
self.updateLayout()
}
CATransaction.begin()
self.reloadData()
CATransaction.commit()
}
}
private lazy var bigDataArr: [VPPayTemplateItem] = []
private lazy var smallDataArr: [VPPayTemplateItem] = []
private var selectedItem: VPPayTemplateItem?
private lazy var bigCollectionViewLayout: UICollectionViewFlowLayout = {
let width = floor((UIScreen.width - 30 - 10) / 2)
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: width, height: 108)
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15)
return layout
}()
private lazy var smallCollectionViewLayout: UICollectionViewFlowLayout = {
let width = floor((UIScreen.width - 30 - 20) / 3)
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: width, height: 108)
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15)
return layout
}()
private lazy var bigCollectionView: VPCollectionView = {
let collectionView = VPCollectionView(frame: .zero, collectionViewLayout: bigCollectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.isScrollEnabled = false
collectionView.register(VPStoreCoinsBigItemView.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
private lazy var smallCollectionView: VPCollectionView = {
let collectionView = VPCollectionView(frame: .zero, collectionViewLayout: smallCollectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.isScrollEnabled = false
collectionView.register(VPStoreCoinsSmallItemView.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
private lazy var bigStackView: UIStackView = {
let view = UIStackView()
view.axis = .horizontal
view.spacing = 10
return view
}()
private lazy var smallStackView: UIStackView = {
let view = UIStackView()
view.axis = .horizontal
view.spacing = 10
return view
}()
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontMedium(ofSize: 13)
label.textColor = .colorFFFFFF()
label.text = "veloria_coin_buy_title".localized
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
vp_setupUI()
updateLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func reloadData() {
self.bigCollectionView.reloadData()
self.smallCollectionView.reloadData()
}
}
extension VPStoreCoinsBuyView {
private func vp_setupUI() {
addSubview(titleLabel)
addSubview(bigCollectionView)
addSubview(smallCollectionView)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.top.equalToSuperview()
}
}
private func updateLayout() {
let top = 25.0
let bigHeight = bigCollectionView.contentSize.height + 1
let smallHeight = smallCollectionView.contentSize.height + 1
if bigDataArr.count > 0 && smallDataArr.count > 0 {
bigCollectionView.snp.remakeConstraints { make in
make.top.equalToSuperview().offset(top)
make.left.right.equalToSuperview()
make.height.equalTo(bigHeight)
}
smallCollectionView.snp.remakeConstraints { make in
make.left.right.equalToSuperview()
make.bottom.equalToSuperview()
make.top.equalTo(bigCollectionView.snp.bottom).offset(10)
make.height.equalTo(smallHeight)
}
} else if bigDataArr.count > 0 {
bigCollectionView.snp.remakeConstraints { make in
make.top.equalToSuperview().offset(top)
make.left.right.equalToSuperview()
make.height.equalTo(bigHeight)
make.bottom.equalToSuperview()
}
smallCollectionView.snp.remakeConstraints { make in
make.left.right.equalToSuperview()
make.top.equalTo(bigCollectionView.snp.bottom).offset(10)
make.height.equalTo(smallHeight)
}
} else if smallDataArr.count > 0 {
smallCollectionView.snp.remakeConstraints { make in
make.top.equalToSuperview().offset(top)
make.left.right.equalToSuperview()
make.height.equalTo(smallHeight)
make.bottom.equalToSuperview()
}
bigCollectionView.snp.remakeConstraints { make in
make.left.right.equalToSuperview()
make.top.equalTo(smallCollectionView.snp.bottom).offset(10)
make.height.equalTo(bigHeight)
}
} else {
bigCollectionView.snp.remakeConstraints { make in
make.top.equalToSuperview().offset(top)
make.left.right.equalToSuperview()
make.height.equalTo(bigHeight)
}
smallCollectionView.snp.remakeConstraints { make in
make.left.right.equalToSuperview()
make.bottom.equalToSuperview()
make.top.equalTo(bigCollectionView.snp.bottom).offset(10)
make.height.equalTo(smallHeight)
}
}
}
}
//MARK: -------------- UICollectionViewDelegate UICollectionViewDataSource --------------
extension VPStoreCoinsBuyView: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let item: VPPayTemplateItem
if collectionView == self.bigCollectionView {
item = self.bigDataArr[indexPath.row]
} else {
item = self.smallDataArr[indexPath.row]
}
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! VPStoreCoinsItemView
cell.item = item
cell.vp_isSelected = item == selectedItem
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == self.bigCollectionView {
return self.bigDataArr.count
} else {
return self.smallDataArr.count
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let item: VPPayTemplateItem
if collectionView == self.bigCollectionView {
item = self.bigDataArr[indexPath.row]
} else {
item = self.smallDataArr[indexPath.row]
}
if selectedItem != item {
selectedItem = item
self.reloadData()
}
VPIAPManager.manager.start(model: item, shortPlayId: shortPlayId, videoId: videoId) { [weak self] finish in
if finish {
VPLoginManager.manager.updateUserInfo(completer: nil)
self?.buyFinishBlock?()
}
}
}
}

View File

@ -0,0 +1,170 @@
//
// VPStoreCoinsItemView.swift
// Veloria
//
// Created by on 2025/6/17.
//
import UIKit
class VPStoreCoinsItemView: VPCollectionViewCell {
var item: VPPayTemplateItem? {
didSet {
coinView.setTitle("\(item?.coins ?? 0)", for: .normal)
priceLabel.text = "\(item?.currency ?? "")\(item?.price ?? "")"
if let sendCoins = item?.send_coins, sendCoins > 0, let coins = item?.coins {
bonusLabel.isHidden = false
bonusRatioView.isHidden = false
bonusLabel.text = "veloria_bonus_count_text".localizedReplace(text: "\(sendCoins)")
let percent = CGFloat(sendCoins) / CGFloat(coins) * 100
bonusRatioLabel.text = String(format: "+%.0f%%", percent)
} else {
bonusLabel.isHidden = true
bonusRatioView.isHidden = true
}
}
}
var vp_isSelected: Bool = false {
didSet {
selectedImageView.isHidden = !vp_isSelected
}
}
private(set) lazy var bgView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
private(set) lazy var coinView: UIButton = {
let view = JXButton(type: .custom)
view.isUserInteractionEnabled = false
view.jx_font = .fontMedium(ofSize: 16)
view.titleDirection = .left
view.space = 3
view.setImage(UIImage(named: "coin_icon_04"), for: .normal)
view.setTitleColor(.colorFFFFFF(), for: .normal)
return view
}()
private(set) lazy var bonusLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
return label
}()
private(set) lazy var bonusRatioView: UIView = {
let view = UIView()
view.addRadius(topLeft: 0, topRight: 8, bottomLeft: 8, bottomRight: 0)
return view
}()
private(set) lazy var bonusRatioLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 11)
label.textColor = .colorFFFFFF()
return label
}()
private(set) lazy var bottomView: VPGradientView = {
let view = VPGradientView()
view.locations = [0, 1]
view.startPoint = .init(x: 0, y: 0.5)
view.endPoint = .init(x: 1, y: 0.5)
view.addRadius(topLeft: 0, topRight: 0, bottomLeft: 8, bottomRight: 8)
return view
}()
private(set) lazy var priceLabel: UILabel = {
let label = UILabel()
return label
}()
private(set) lazy var selectedImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
vp_setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func vp_setupUI() {
addSubview(bgView)
bgView.addSubview(coinView)
bgView.addSubview(bonusLabel)
bgView.addSubview(bottomView)
bottomView.addSubview(priceLabel)
bgView.addSubview(bonusRatioView)
bonusRatioView.addSubview(bonusRatioLabel)
bgView.addSubview(selectedImageView)
bgView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
coinView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(28)
}
bonusLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(53)
}
bottomView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(28)
}
priceLabel.snp.makeConstraints { make in
make.center.equalToSuperview()
}
bonusRatioView.snp.makeConstraints { make in
make.right.top.equalToSuperview()
make.height.equalTo(16)
}
bonusRatioLabel.snp.makeConstraints { make in
make.center.equalToSuperview()
make.left.equalToSuperview().offset(5)
}
selectedImageView.snp.makeConstraints { make in
make.bottom.equalToSuperview()
make.right.equalToSuperview()
}
}
}
extension VPStoreCoinsItemView {
static func createView(item: VPPayTemplateItem) -> VPStoreCoinsItemView {
let view: VPStoreCoinsItemView
if item.size == .big {
view = VPStoreCoinsBigItemView()
} else {
view = VPStoreCoinsSmallItemView()
}
view.item = item
return view
}
}

View File

@ -0,0 +1,73 @@
//
// VPStoreCoinsSmallItemView.swift
// Veloria
//
// Created by on 2025/6/17.
//
import UIKit
class VPStoreCoinsSmallItemView: VPStoreCoinsItemView {
override var intrinsicContentSize: CGSize {
let width = floor((UIScreen.width - 30 - 20) / 3)
return .init(width: width, height: 108)
}
override var item: VPPayTemplateItem? {
didSet {
if let mark = item?.corner_marker, !mark.isEmpty {
hotBgView.isHidden = false
hotLabel.text = mark
} else {
hotBgView.isHidden = true
}
}
}
private lazy var hotBgView: UIView = {
let view = UIView()
view.backgroundColor = .colorBE0069()
view.addRadius(topLeft: 8, topRight: 0, bottomLeft: 0, bottomRight: 8)
view.layer.zPosition = 0
return view
}()
private lazy var hotLabel: UILabel = {
let label = UILabel()
label.textColor = .colorFFFFFF()
label.font = .fontRegular(ofSize: 11)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
bgView.image = UIImage(named: "coin_small_bg_image")
bonusLabel.textColor = .color05CEA0()
bottomView.colors = [UIColor.color05CEA0(alpha: 0.25).cgColor, UIColor.color05CEA0(alpha: 0.25).cgColor]
priceLabel.font = .fontRegular(ofSize: 12)
priceLabel.textColor = .colorFFFFFF()
bonusRatioView.backgroundColor = .color05CEA0(alpha: 0.5)
selectedImageView.image = UIImage(named: "selected_icon_01")
bgView.addSubview(hotBgView)
hotBgView.addSubview(hotLabel)
hotBgView.snp.makeConstraints { make in
make.left.top.equalToSuperview()
make.height.equalTo(16)
}
hotLabel.snp.makeConstraints { make in
make.center.equalToSuperview()
make.left.equalToSuperview().offset(5)
}
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -0,0 +1,111 @@
//
// VPStoreVipBuyView.swift
// Veloria
//
// Created by on 2025/6/17.
//
import UIKit
class VPStoreVipBuyView: UIView {
override var intrinsicContentSize: CGSize {
var height: CGFloat = 1
if dataArr.count > 0, collectionView.contentSize.height > 0 {
height = collectionView.contentSize.height + 1
}
return .init(width: UIScreen.width, height: height)
}
var buyFinishBlock: (() -> Void)?
var shortPlayId: String?
var videoId: String?
var dataArr: [VPPayTemplateItem] = [] {
didSet {
UIView.performWithoutAnimation { [weak self] in
self?.collectionView.reloadData()
}
self.collectionView.performBatchUpdates(nil) { [weak self] _ in
self?.invalidateIntrinsicContentSize()
}
}
}
private var currentIndex: Int?
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: UIScreen.width - 30, height: 130)
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 10
layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15)
return layout
}()
private lazy var collectionView: VPCollectionView = {
let collectionView = VPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.isScrollEnabled = false
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(VPVipBuyCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
override init(frame: CGRect) {
super.init(frame: frame)
vp_setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension VPStoreVipBuyView {
private func vp_setupUI() {
addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
//MARK: -------------- UICollectionViewDelegate UICollectionViewDataSource --------------
extension VPStoreVipBuyView: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! VPVipBuyCell
cell.item = dataArr[indexPath.row]
cell.vp_isSelected = indexPath.row == currentIndex
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
self.dataArr.count
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if currentIndex != indexPath.row {
currentIndex = indexPath.row
collectionView.reloadData()
}
VPIAPManager.manager.start(model: dataArr[indexPath.row], shortPlayId: shortPlayId, videoId: videoId) { [weak self] finish in
if finish {
VPLoginManager.manager.updateUserInfo(completer: nil)
self?.buyFinishBlock?()
}
}
}
}

View File

@ -14,42 +14,62 @@ class VPVipBuyCell: ZKCycleScrollViewCell {
didSet {
if let key = item?.vip_type_key?.rawValue {
bgImageView.image = UIImage(named: "vip_buy_bg_\(key)")
bgIconImageView.image = UIImage(named: "vip_buy_bg_icon_\(key)")
}
// vipNameLabel.text = item?.vip_type_key?.getText()
vipNameLabel.text = item?.title
unitLabel.text = item?.currency
moneyLabel.text = item?.price
durationLabel.text = "/\(item?.vip_type_key?.getText() ?? "")"
desLabel.text = item?.sp_description
var tipText = "veloria_store_auto_renew".localized
if let coin = item?.send_coins, coin > 0 {
sendCoinBgView.isHidden = false
sendCoinView.isHidden = false
let text = "veloria_extra".localized + " \(coin)"
sendCoinView.setTitle("+" + text, for: .normal)
tipText += "\n"
tipText += "veloria_store_donate_coins_ios".localizedReplace(text: "veloria_days_count_text".localizedReplace(text: "\(item?.send_coin_ttl ?? 0)"))
} else {
sendCoinBgView.isHidden = true
sendCoinView.isHidden = true
}
tipLabel.text = tipText
var colors: [CGColor] = []
switch item?.vip_type_key {
case .week:
colors = [UIColor.color64A3A7().cgColor, UIColor.color416767().cgColor]
sendCoinBgView.colors = [UIColor.colorB2E7EA().cgColor, UIColor.colorB2E7EA(alpha: 0).cgColor]
sendCoinView.setTitleColor(.color416767(), for: .normal)
sendCoinBgView.colors = [UIColor.colorBDFFFB().cgColor, UIColor.color7AD9D4().cgColor]
sendCoinView.setTitleColor(.color16706A(), for: .normal)
desLabel.textColor = .color416767()
desBgView.colors = [UIColor.colorB2E7EA().cgColor, UIColor.colorB2E7EA(alpha: 0).cgColor]
tipLabel.textColor = .color8AAEA6()
case .month:
colors = [UIColor.color9C7565().cgColor, UIColor.color573D31().cgColor]
sendCoinBgView.colors = [UIColor.colorFFE6CE().cgColor, UIColor.colorFFE6CE(alpha: 0).cgColor]
sendCoinView.setTitleColor(.color573D31(), for: .normal)
case .quarter:
colors = [UIColor.color647DA7().cgColor, UIColor.color414867().cgColor]
sendCoinBgView.colors = [UIColor.colorD6E5F9().cgColor, UIColor.colorD6E5F9(alpha: 0).cgColor]
sendCoinView.setTitleColor(.color303962(), for: .normal)
sendCoinBgView.colors = [UIColor.colorADCFFF().cgColor, UIColor.color7CA1D7().cgColor]
sendCoinView.setTitleColor(.color214170(), for: .normal)
desLabel.textColor = .color303962()
desBgView.colors = [UIColor.colorD6E5F9().cgColor, UIColor.colorD6E5F9(alpha: 0).cgColor]
tipLabel.textColor = .color8790B7()
case .quarter:
colors = [UIColor.color7869FF().cgColor, UIColor.color9F45FF().cgColor]
sendCoinBgView.colors = [UIColor.colorDBC7FF().cgColor, UIColor.color975DFF().cgColor]
sendCoinView.setTitleColor(.color510087(), for: .normal)
desLabel.textColor = .color5F1EB9()
desBgView.colors = [UIColor.colorCABCFF().cgColor, UIColor.colorCABCFF(alpha: 0).cgColor]
tipLabel.textColor = .colorA395D9()
case .year:
colors = [UIColor.color9C6586().cgColor, UIColor.color57314F().cgColor]
sendCoinBgView.colors = [UIColor.colorFFD8F5().cgColor, UIColor.colorFFD8F5(alpha: 0).cgColor]
sendCoinView.setTitleColor(.color674162(), for: .normal)
colors = [UIColor.color9C7565().cgColor, UIColor.color573D31().cgColor]
sendCoinBgView.colors = [UIColor.colorFBF2C7().cgColor, UIColor.colorA87A46().cgColor]
sendCoinView.setTitleColor(.color683D00(), for: .normal)
desLabel.textColor = .color573D31()
desBgView.colors = [UIColor.colorFFE6CE().cgColor, UIColor.colorFFE6CE(alpha: 0).cgColor]
tipLabel.textColor = .colorAC978D()
default:
break
}
@ -59,7 +79,6 @@ class VPVipBuyCell: ZKCycleScrollViewCell {
unitLabel.gradientLayer.colors = colors
moneyLabel.gradientLayer.colors = colors
durationLabel.gradientLayer.colors = colors
durationLabel.gradientLayer.colors = colors
}
}
@ -74,27 +93,48 @@ class VPVipBuyCell: ZKCycleScrollViewCell {
return imageView
}()
private lazy var bgIconImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
private lazy var vipNameLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontBold(ofSize: 16)
label.font = .fontMedium(ofSize: 12)
return label
}()
private lazy var unitLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontRegular(ofSize: 14)
label.font = .fontRegular(ofSize: 18)
return label
}()
private lazy var moneyLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontAaHouDiHei(ofSize: 22)
label.font = .fontAaHouDiHei(ofSize: 32)
return label
}()
private lazy var durationLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontRegular(ofSize: 14)
label.font = .fontMedium(ofSize: 16)
return label
}()
private lazy var desBgView: VPGradientView = {
let view = VPGradientView()
view.locations = [0, 1]
view.startPoint = .init(x: 0, y: 0.5)
view.endPoint = .init(x: 1, y: 0.5)
view.layer.cornerRadius = 8
view.layer.masksToBounds = true
return view
}()
private lazy var desLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 10)
return label
}()
@ -103,8 +143,7 @@ class VPVipBuyCell: ZKCycleScrollViewCell {
view.locations = [0, 1]
view.startPoint = .init(x: 0, y: 0.5)
view.endPoint = .init(x: 1, y: 0.5)
view.layer.cornerRadius = 6
view.layer.masksToBounds = true
view.addRadius(topLeft: 10, topRight: 0, bottomLeft: 0, bottomRight: 10)
return view
}()
@ -113,11 +152,18 @@ class VPVipBuyCell: ZKCycleScrollViewCell {
view.isUserInteractionEnabled = false
view.titleDirection = .left
view.space = 4
view.jx_font = .fontRegular(ofSize: 12)
view.jx_font = .fontMedium(ofSize: 12)
view.setImage(UIImage(named: "coin_icon_02"), for: .normal)
return view
}()
private lazy var tipLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.font = .fontRegular(ofSize: 10)
return label
}()
private lazy var selectedImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "selected_icon_01"))
return imageView
@ -139,56 +185,81 @@ extension VPVipBuyCell {
private func vp_setupUI() {
contentView.addSubview(bgImageView)
contentView.addSubview(vipNameLabel)
contentView.addSubview(unitLabel)
contentView.addSubview(moneyLabel)
contentView.addSubview(durationLabel)
contentView.addSubview(sendCoinBgView)
contentView.addSubview(sendCoinView)
contentView.addSubview(selectedImageView)
contentView.addSubview(bgIconImageView)
bgImageView.addSubview(vipNameLabel)
bgImageView.addSubview(unitLabel)
bgImageView.addSubview(moneyLabel)
bgImageView.addSubview(durationLabel)
bgImageView.addSubview(sendCoinBgView)
sendCoinBgView.addSubview(sendCoinView)
bgImageView.addSubview(desBgView)
desBgView.addSubview(desLabel)
bgImageView.addSubview(tipLabel)
bgImageView.addSubview(selectedImageView)
bgImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(10)
}
bgIconImageView.snp.makeConstraints { make in
make.top.equalToSuperview()
make.right.equalToSuperview()
}
vipNameLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(14)
make.top.equalToSuperview().offset(35)
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(10)
make.height.equalTo(22)
}
unitLabel.snp.makeConstraints { make in
make.left.equalTo(vipNameLabel)
make.top.equalTo(vipNameLabel.snp.bottom).offset(17)
make.height.equalTo(20)
make.top.equalTo(vipNameLabel.snp.bottom).offset(10)
make.height.equalTo(25)
}
moneyLabel.snp.makeConstraints { make in
make.left.equalTo(unitLabel.snp.right)
make.bottom.equalTo(unitLabel)
make.bottom.equalTo(unitLabel).offset(3)
}
durationLabel.snp.makeConstraints { make in
make.bottom.equalTo(moneyLabel).offset(-2)
make.bottom.equalTo(unitLabel).offset(-2)
make.left.equalTo(moneyLabel.snp.right)
make.height.equalTo(20)
make.height.equalTo(22)
}
sendCoinBgView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(14)
make.bottom.equalToSuperview().offset(-10)
make.right.bottom.equalToSuperview()
make.height.equalTo(24)
make.width.equalTo(105)
}
sendCoinView.snp.makeConstraints { make in
make.centerY.equalTo(sendCoinBgView)
make.left.equalTo(sendCoinBgView).offset(11)
make.centerY.equalToSuperview()
make.centerX.equalToSuperview()
make.left.equalToSuperview().offset(10)
}
desBgView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.bottom.equalToSuperview().offset(-35)
make.height.equalTo(16)
}
desLabel.snp.makeConstraints { make in
make.center.equalToSuperview()
make.left.equalToSuperview().offset(7)
}
tipLabel.snp.makeConstraints { make in
make.left.equalTo(desBgView)
make.top.equalTo(desBgView.snp.bottom).offset(5)
}
selectedImageView.snp.makeConstraints { make in
make.left.equalToSuperview()
make.top.equalToSuperview().offset(18)
make.top.equalToSuperview()
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -5,12 +5,12 @@
"scale" : "1x"
},
{
"filename" : "顶部bg@2x.png",
"filename" : "hot@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "顶部bg@3x.png",
"filename" : "hot@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 B

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

View File

@ -5,12 +5,12 @@
"scale" : "1x"
},
{
"filename" : "Recharge & Unlock More@2x.png",
"filename" : "Component 65@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Recharge & Unlock More@3x.png",
"filename" : "Component 65@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 836 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -5,12 +5,12 @@
"scale" : "1x"
},
{
"filename" : "香槟金色会员卡bg@2x.png",
"filename" : "银色色会员卡bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "香槟金色会员卡bg@3x.png",
"filename" : "银色色会员卡bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 389 KiB

View File

@ -5,12 +5,12 @@
"scale" : "1x"
},
{
"filename" : "香槟金色会员卡bg@2x.png",
"filename" : "色会员卡bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "香槟金色会员卡bg@3x.png",
"filename" : "色会员卡bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 311 KiB

View File

@ -5,12 +5,12 @@
"scale" : "1x"
},
{
"filename" : "香槟金色会员卡bg@2x.png",
"filename" : "金色会员卡bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "香槟金色会员卡bg@3x.png",
"filename" : "金色会员卡bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

View File

@ -94,6 +94,7 @@
"veloria_year" = "1 year";
"veloria_days_count_text" = "## days";
"veloria_last_play_episode" = "Last time Episode ##";
"veloria_coin_buy_title" = "Top Up | Indefinitely use";
"veloria_bonus_count_text" = "+## Bonus";