From cbac290cf799f4ccf265e87e187b08b1fd32a787 Mon Sep 17 00:00:00 2001 From: zjx Date: Fri, 30 May 2025 13:33:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=85=E5=80=BC=E9=A1=B5=E9=9D=A2UI=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Veloria.xcodeproj/project.pbxproj | 8 + Veloria/Base/Extension/UIButton+VPAdd.swift | 15 +- Veloria/Base/Extension/UIColor+VPAdd.swift | 32 +++ Veloria/Base/Extension/UIView+VPAdd.swift | 15 +- Veloria/Base/Networking/Base/VPNetwork.swift | 8 +- Veloria/Base/View/VPGradientButton.swift | 44 ++++ Veloria/Base/View/VPGradientLabel.swift | 5 +- .../Controller/VPCoinsViewController.swift | 166 ++++++++++++++- .../Controller/VPVipViewController.swift | 57 +++++- .../Wallet/Model/VPPayTemplateItem.swift | 8 +- .../Class/Wallet/View/VPCoinsBuyCell.swift | 189 ++++++++++++++++++ Veloria/Class/Wallet/View/VPVipBuyCell.swift | 88 +++++++- Veloria/Libs/User/VPUserInfo.swift | 4 + .../icon/coin_icon_02.imageset/Contents.json | 22 ++ .../icon/coin_icon_02.imageset/金币1 2@2x.png | Bin 0 -> 2453 bytes .../icon/coin_icon_02.imageset/金币1 2@3x.png | Bin 0 -> 4671 bytes .../icon/coin_icon_03.imageset/Contents.json | 22 ++ .../icon/coin_icon_03.imageset/金币 2@2x.png | Bin 0 -> 4092 bytes .../icon/coin_icon_03.imageset/金币 2@3x.png | Bin 0 -> 8047 bytes .../icon/coin_icon_04.imageset/Contents.json | 22 ++ .../icon/coin_icon_04.imageset/金币1 3@2x.png | Bin 0 -> 5726 bytes .../icon/coin_icon_04.imageset/金币1 3@3x.png | Bin 0 -> 10916 bytes .../Component 63@2x.png | Bin 0 -> 740 bytes .../Component 63@3x.png | Bin 0 -> 1080 bytes .../selected_icon_01.imageset/Contents.json | 22 ++ Veloria/Source/en.lproj/Localizable.strings | 18 +- 26 files changed, 709 insertions(+), 36 deletions(-) create mode 100644 Veloria/Base/View/VPGradientButton.swift create mode 100644 Veloria/Class/Wallet/View/VPCoinsBuyCell.swift create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/Contents.json create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/金币1 2@2x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/金币1 2@3x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/Contents.json create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/金币 2@2x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/金币 2@3x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/Contents.json create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/金币1 3@2x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/金币1 3@3x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/selected_icon_01.imageset/Component 63@2x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/selected_icon_01.imageset/Component 63@3x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/selected_icon_01.imageset/Contents.json diff --git a/Veloria.xcodeproj/project.pbxproj b/Veloria.xcodeproj/project.pbxproj index d5957c5..8fbb835 100644 --- a/Veloria.xcodeproj/project.pbxproj +++ b/Veloria.xcodeproj/project.pbxproj @@ -161,6 +161,8 @@ BFF5AFC02DE837D60044227A /* VPPayTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFBF2DE837D60044227A /* VPPayTemplateModel.swift */; }; BFF5AFC22DE837FC0044227A /* VPPayTemplateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFC12DE837FC0044227A /* VPPayTemplateItem.swift */; }; BFF5AFC42DE84F9C0044227A /* Aa厚底黑.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BFF5AFC32DE84F9C0044227A /* Aa厚底黑.ttf */; }; + BFF5AFC62DE863C00044227A /* VPGradientButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFC52DE863C00044227A /* VPGradientButton.swift */; }; + BFF5AFC82DE9473B0044227A /* VPCoinsBuyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFC72DE9473B0044227A /* VPCoinsBuyCell.swift */; }; F939C04AD4003BA127F15C28 /* Pods_Veloria.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F57E87E765BF8D72A43DCA /* Pods_Veloria.framework */; }; /* End PBXBuildFile section */ @@ -328,6 +330,8 @@ BFF5AFBF2DE837D60044227A /* VPPayTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayTemplateModel.swift; sourceTree = ""; }; BFF5AFC12DE837FC0044227A /* VPPayTemplateItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayTemplateItem.swift; sourceTree = ""; }; BFF5AFC32DE84F9C0044227A /* Aa厚底黑.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Aa厚底黑.ttf"; sourceTree = ""; }; + BFF5AFC52DE863C00044227A /* VPGradientButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPGradientButton.swift; sourceTree = ""; }; + BFF5AFC72DE9473B0044227A /* VPCoinsBuyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPCoinsBuyCell.swift; sourceTree = ""; }; E0BDA3570E00C90877E45AA0 /* Pods-VideoPlayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VideoPlayer.debug.xcconfig"; path = "Target Support Files/Pods-VideoPlayer/Pods-VideoPlayer.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -454,6 +458,7 @@ children = ( 1B056E752DDB35C5007EE38D /* TabBar */, 1B056E7A2DDB37BA007EE38D /* VPGradientView.swift */, + BFF5AFC52DE863C00044227A /* VPGradientButton.swift */, BF0FA7092DDC69C800C9E5F2 /* VPTableViewCell.swift */, BF0FA71A2DDC7FF200C9E5F2 /* VPImageView.swift */, BF0FA7252DDC8F7600C9E5F2 /* VPCollectionView.swift */, @@ -972,6 +977,7 @@ children = ( BFF5AFB52DE803A30044227A /* VPVipPrivilegeItemView.swift */, BFF5AFB72DE832580044227A /* VPVipBuyCell.swift */, + BFF5AFC72DE9473B0044227A /* VPCoinsBuyCell.swift */, ); path = View; sourceTree = ""; @@ -1192,6 +1198,7 @@ BFF5AFC22DE837FC0044227A /* VPPayTemplateItem.swift in Sources */, BF0FA6DA2DDC5CB600C9E5F2 /* VPLoginManager.swift in Sources */, BF0FA74A2DDF04E200C9E5F2 /* VPPlayerProtocol.swift in Sources */, + BFF5AFC82DE9473B0044227A /* VPCoinsBuyCell.swift in Sources */, BF0FA72C2DDD7B7300C9E5F2 /* VPHomeRankingContentCell.swift in Sources */, BF0FA7AF2DE443E000C9E5F2 /* VPMeViewController.swift in Sources */, BF0FA7942DE16E9300C9E5F2 /* JXTagView.swift in Sources */, @@ -1204,6 +1211,7 @@ BF0FA7912DE16CBF00C9E5F2 /* VPSearchHistoryView.swift in Sources */, BF0FA7992DE1951A00C9E5F2 /* VPMyListViewController.swift in Sources */, BF0FA7452DDF027900C9E5F2 /* VPPlayer.swift in Sources */, + BFF5AFC62DE863C00044227A /* VPGradientButton.swift in Sources */, BFF5AFA82DE704DC0044227A /* VPMeCoinCell.swift in Sources */, BFF5AFAE2DE717BB0044227A /* VPVipPageViewController.swift in Sources */, BF0FA70E2DDC6ACC00C9E5F2 /* VPHomeItemContentCell.swift in Sources */, diff --git a/Veloria/Base/Extension/UIButton+VPAdd.swift b/Veloria/Base/Extension/UIButton+VPAdd.swift index 149b176..1f00a57 100644 --- a/Veloria/Base/Extension/UIButton+VPAdd.swift +++ b/Veloria/Base/Extension/UIButton+VPAdd.swift @@ -23,9 +23,12 @@ extension UIButton { vp_bt_layoutSubviews() bt_gradientLayer?.frame = self.bounds - bt_gradientBorder?.frame = self.bounds - let path = UIBezierPath(roundedRect: bounds.insetBy(dx: 0.5, dy: 0.5), cornerRadius: layer.cornerRadius) - bt_gradientBorderShapeLayer?.path = path.cgPath + + if let border = bt_gradientBorder, let shapeLayer = bt_gradientBorderShapeLayer { + border.frame = self.bounds + let path = UIBezierPath(roundedRect: bounds.insetBy(dx: shapeLayer.lineWidth / 2, dy: shapeLayer.lineWidth / 2), cornerRadius: layer.cornerRadius) + shapeLayer.path = path.cgPath + } } @@ -86,16 +89,16 @@ extension UIButton { ///设置渐变边框 - func bt_setGradientBorder() { + func bt_setGradientBorder(lineWidth: CGFloat = 1, colors: [CGColor] = [UIColor.color05CEA0().cgColor, UIColor.color7C174F().cgColor]) { if bt_gradientBorder == nil { let gLayer = CAGradientLayer() - gLayer.colors = [UIColor.color05CEA0().cgColor, UIColor.color7C174F().cgColor] + gLayer.colors = colors gLayer.locations = [0, 0.8] gLayer.startPoint = .init(x: 0, y: 0.3) gLayer.endPoint = .init(x: 1, y: 0.8) let shapeLayer = CAShapeLayer() - shapeLayer.lineWidth = 1 + shapeLayer.lineWidth = lineWidth shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = UIColor.black.cgColor gLayer.mask = shapeLayer diff --git a/Veloria/Base/Extension/UIColor+VPAdd.swift b/Veloria/Base/Extension/UIColor+VPAdd.swift index 46e3667..3797272 100644 --- a/Veloria/Base/Extension/UIColor+VPAdd.swift +++ b/Veloria/Base/Extension/UIColor+VPAdd.swift @@ -161,4 +161,36 @@ extension UIColor { static func color57314F(alpha: CGFloat = 1) -> UIColor { return UIColor(rgb: 0x57314F, alpha: alpha) } + + static func colorB2E7EA(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xB2E7EA, alpha: alpha) + } + + static func colorFFE6CE(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xFFE6CE, alpha: alpha) + } + + static func colorD6E5F9(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xD6E5F9, alpha: alpha) + } + + static func colorFFD8F5(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xFFD8F5, alpha: alpha) + } + + static func color303962(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0x303962, alpha: alpha) + } + + static func color674162(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0x674162, alpha: alpha) + } + + static func colorBE0069(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xBE0069, alpha: alpha) + } + + static func color00211A(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0x00211A, alpha: alpha) + } } diff --git a/Veloria/Base/Extension/UIView+VPAdd.swift b/Veloria/Base/Extension/UIView+VPAdd.swift index b467a01..608efa3 100644 --- a/Veloria/Base/Extension/UIView+VPAdd.swift +++ b/Veloria/Base/Extension/UIView+VPAdd.swift @@ -31,11 +31,14 @@ extension UIView { effectView.frame = self.bounds } + CATransaction.begin() + CATransaction.setDisableActions(true) if let border = vp_gradientBorder { border.frame = self.bounds let path = UIBezierPath(roundedRect: bounds.insetBy(dx: 0.5, dy: 0.5), cornerRadius: layer.cornerRadius) vp_gradientBorderShapeLayer?.path = path.cgPath } + CATransaction.commit() } } @@ -124,10 +127,16 @@ extension UIView { } ///设置渐变边框 - func vp_setGradientBorder() { - if vp_gradientBorder == nil { + func vp_setGradientBorder(colors: [CGColor] = [UIColor.color05CEA0().cgColor, UIColor.color7C174F().cgColor]) { + if let gLayer = vp_gradientBorder { + CATransaction.begin() + CATransaction.setDisableActions(true) + gLayer.colors = colors + CATransaction.commit() + + } else { let gLayer = CAGradientLayer() - gLayer.colors = [UIColor.color05CEA0().cgColor, UIColor.color7C174F().cgColor] + gLayer.colors = colors gLayer.locations = [0, 0.8] gLayer.startPoint = .init(x: 0, y: 0.3) gLayer.endPoint = .init(x: 1, y: 0.8) diff --git a/Veloria/Base/Networking/Base/VPNetwork.swift b/Veloria/Base/Networking/Base/VPNetwork.swift index 95a2690..254ffce 100644 --- a/Veloria/Base/Networking/Base/VPNetwork.swift +++ b/Veloria/Base/Networking/Base/VPNetwork.swift @@ -76,7 +76,7 @@ class VPNetwork: NSObject { var res = VPNetworkResponse() res.code = -1 if parameters.isToast { - VPToast.show(text: "movia_error".localized) + VPToast.show(text: "Error".localized) } completion?(res) } else { @@ -128,7 +128,7 @@ class VPNetwork: NSObject { var res = VPNetworkResponse() res.code = -1 if parameters.isToast { - VPToast.show(text: "movia_error".localized) + VPToast.show(text: "Error".localized) } completion?(res) } @@ -137,7 +137,7 @@ class VPNetwork: NSObject { var res = VPNetworkResponse() res.code = -1 if parameters.isToast { - VPToast.show(text: "movia_network_toast_01".localized) + VPToast.show(text: "network_toast_01".localized) } completion?(res) break @@ -162,7 +162,7 @@ class VPNetwork: NSObject { } else { var response = VPNetworkResponse() response.code = -1 - response.msg = "movia_error".localized + response.msg = "Error".localized return response } } diff --git a/Veloria/Base/View/VPGradientButton.swift b/Veloria/Base/View/VPGradientButton.swift new file mode 100644 index 0000000..5b5c5f2 --- /dev/null +++ b/Veloria/Base/View/VPGradientButton.swift @@ -0,0 +1,44 @@ +// +// VPGradientButton.swift +// Veloria +// +// Created by 湖南秦九 on 2025/5/29. +// + +import UIKit + +class VPGradientButton: UIButton { + + override class var layerClass: AnyClass { + return CAGradientLayer.self + } + + var gradientLayer: CAGradientLayer { + return self.layer as! CAGradientLayer + } + + var locations: [NSNumber]? { + didSet { + self.gradientLayer.locations = locations + } + } + + var colors: [CGColor]? { + didSet { + self.gradientLayer.colors = colors + } + } + + var startPoint: CGPoint = .zero { + didSet { + self.gradientLayer.startPoint = startPoint + } + } + + var endPoint: CGPoint = .zero { + didSet { + self.gradientLayer.endPoint = endPoint + } + } + +} diff --git a/Veloria/Base/View/VPGradientLabel.swift b/Veloria/Base/View/VPGradientLabel.swift index 382a329..a240f98 100644 --- a/Veloria/Base/View/VPGradientLabel.swift +++ b/Veloria/Base/View/VPGradientLabel.swift @@ -37,6 +37,9 @@ class VPGradientLabel: UILabel { override func layoutSubviews() { super.layoutSubviews() + CATransaction.begin() + CATransaction.setDisableActions(true) + gradientLayer.frame = bounds let string = NSMutableAttributedString(attributedString: attributedText ?? NSAttributedString(string: text ?? "")) string.color = .colorFFFFFF() @@ -47,9 +50,9 @@ class VPGradientLabel: UILabel { textLayer.frame = bounds textLayer.alignmentMode = .center textLayer.contentsScale = UIScreen.main.scale - gradientLayer.mask = textLayer + CATransaction.commit() } } diff --git a/Veloria/Class/Wallet/Controller/VPCoinsViewController.swift b/Veloria/Class/Wallet/Controller/VPCoinsViewController.swift index adb4585..690c866 100644 --- a/Veloria/Class/Wallet/Controller/VPCoinsViewController.swift +++ b/Veloria/Class/Wallet/Controller/VPCoinsViewController.swift @@ -11,27 +11,171 @@ class VPCoinsViewController: VPViewController { var dataArr: [VPPayTemplateItem] = [] { didSet { -// self.collectionView.reloadData() + reloadData() + } } + + private lazy var selectedIndex = 0 + + //MARK: UI属性 + private lazy var scrollView: UIScrollView = { + let scrollView = VPScrollView() + scrollView.showsVerticalScrollIndicator = false + return scrollView + }() + + private lazy var iconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "coin_icon_03")) + return imageView + }() + + private lazy var iconTextLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 15) + label.textColor = .colorFFFFFF() + label.text = "Get More Coins".localized + return label + }() + + private lazy var coinsCountLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 13) + label.textColor = .colorBE0069() + return label + }() + + private lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let itemWidth = floor((UIScreen.width - 30 - 20) / 3) + + let layout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 10 + layout.minimumInteritemSpacing = 10 + layout.itemSize = .init(width: itemWidth, height: 108) + 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.delegate = self + collectionView.dataSource = self + collectionView.isScrollEnabled = false + collectionView.register(VPCoinsBuyCell.self, forCellWithReuseIdentifier: "cell") + return collectionView + }() + + private lazy var tipLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFFFFFF(alpha: 0.5) + label.numberOfLines = 0 + label.text = "kStoreTips".localized + return label + }() override func viewDidLoad() { super.viewDidLoad() self.bgImageView.isHidden = true self.view.backgroundColor = .clear + updateCoin() + vp_setupUI() + reloadData() } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. + + private func updateCoin() { + let coinCountStr = "\(VPLoginManager.manager.userInfo?.totalCoin ?? 0)" + let text = String(format: "Coins: %@".localized, coinCountStr) + let coinRange = text.ocString().range(of: coinCountStr) + + let string = NSMutableAttributedString(string: text) + string.color = .colorFFFFFF() + string.setColor(.colorBE0069(), range: coinRange) + + coinsCountLabel.attributedText = string + } + + + private func reloadData() { + CATransaction.setCompletionBlock { [weak self] in + guard let self = self else { return } + if self.collectionView.superview != nil { + self.collectionView.snp.updateConstraints { make in + make.height.equalTo(self.collectionView.contentSize.height + 1) + } + } + } + CATransaction.begin() + self.collectionView.reloadData() + CATransaction.commit() + } +} + +extension VPCoinsViewController { + + private func vp_setupUI() { + view.addSubview(scrollView) + scrollView.addSubview(iconImageView) + scrollView.addSubview(iconTextLabel) + scrollView.addSubview(coinsCountLabel) + scrollView.addSubview(collectionView) + scrollView.addSubview(tipLabel) + + scrollView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + iconImageView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.top.equalToSuperview().offset(20) + } + + iconTextLabel.snp.makeConstraints { make in + make.centerY.equalTo(iconImageView) + make.left.equalTo(iconImageView.snp.right).offset(7) + } + + coinsCountLabel.snp.makeConstraints { make in + make.centerY.equalTo(iconImageView) + make.right.equalTo(self.view).offset(-15) + } + + collectionView.snp.makeConstraints { make in + make.left.centerX.equalToSuperview() + make.top.equalToSuperview().offset(62) + make.height.equalTo(self.collectionView.contentSize.height + 1) + } + + tipLabel.snp.makeConstraints { make in + make.top.equalTo(collectionView.snp.bottom).offset(14) + make.left.equalToSuperview().offset(15) + make.width.lessThanOrEqualTo(UIScreen.width - 30) + make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 10)) + } + } + +} + +//MARK: -------------- UICollectionViewDelegate UICollectionViewDataSource -------------- +extension VPCoinsViewController: UICollectionViewDelegate, UICollectionViewDataSource { + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! VPCoinsBuyCell + cell.item = self.dataArr[indexPath.row] + cell.vp_isSelected = indexPath.row == selectedIndex + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.dataArr.count + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + vpLog(message: indexPath.row) + self.selectedIndex = indexPath.row + collectionView.reloadData() } - */ - } diff --git a/Veloria/Class/Wallet/Controller/VPVipViewController.swift b/Veloria/Class/Wallet/Controller/VPVipViewController.swift index 02991d3..2636256 100644 --- a/Veloria/Class/Wallet/Controller/VPVipViewController.swift +++ b/Veloria/Class/Wallet/Controller/VPVipViewController.swift @@ -16,8 +16,11 @@ class VPVipViewController: VPViewController { } } + private lazy var currentIndex: Int = 0 + private lazy var scrollView: UIScrollView = { let scrollView = VPScrollView() + scrollView.showsVerticalScrollIndicator = false return scrollView }() @@ -103,6 +106,29 @@ class VPVipViewController: VPViewController { return collectionView }() + private lazy var tipLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFFFFFF(alpha: 0.5) + label.numberOfLines = 0 + label.text = "kStoreTips".localized + return label + }() + +// private lazy var buyButton: UIButton = { +// let button = VPGradientButton(type: .custom) +// button.layer.cornerRadius = 24 +// button.layer.masksToBounds = true +// button.bt_setGradientBorder() +// button.colors = [UIColor.color05CEA0(alpha: 0.3).cgColor, UIColor.color7C174F(alpha: 0.3).cgColor] +// button.locations = [0, 1] +// button.startPoint = .init(x: 0, y: 0.3) +// button.endPoint = .init(x: 1, y: 0.8) +// button.setTitle("Buy Now".localized, for: .normal) +// button.setTitleColor(.colorFFFFFF(), for: .normal) +// button.titleLabel?.font = .fontMedium(ofSize: 14) +// return button +// }() override func viewDidLoad() { @@ -124,9 +150,13 @@ extension VPVipViewController { scrollView.addSubview(iconTextLabel) scrollView.addSubview(stackView) scrollView.addSubview(collectionView) + scrollView.addSubview(tipLabel) +// view.addSubview(buyButton) scrollView.snp.makeConstraints { make in - make.edges.equalToSuperview() + make.left.right.top.equalToSuperview() +// make.bottom.equalTo(buyButton.snp.top).offset(-10) + make.bottom.equalToSuperview() } iconImageView.snp.makeConstraints { make in @@ -150,8 +180,22 @@ extension VPVipViewController { make.centerX.equalToSuperview() make.top.equalTo(stackView.snp.bottom).offset(7) make.height.equalTo(collectionViewLayout.itemSize.height) - make.bottom.equalToSuperview() } + + tipLabel.snp.makeConstraints { make in + make.top.equalTo(collectionView.snp.bottom).offset(14) + make.left.equalToSuperview().offset(15) + make.width.lessThanOrEqualTo(UIScreen.width - 30) +// make.bottom.equalToSuperview().offset(-10) + make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 10)) + } + +// buyButton.snp.makeConstraints { make in +// make.left.equalToSuperview().offset(15) +// make.centerX.equalToSuperview() +// make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 10)) +// make.height.equalTo(48) +// } } } @@ -161,10 +205,19 @@ extension VPVipViewController: UICollectionViewDelegate, UICollectionViewDataSou 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 { return dataArr.count } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if currentIndex != indexPath.row { + currentIndex = indexPath.row + self.collectionView.reloadData() + } + + } } diff --git a/Veloria/Class/Wallet/Model/VPPayTemplateItem.swift b/Veloria/Class/Wallet/Model/VPPayTemplateItem.swift index 3a0fb24..bba26ea 100644 --- a/Veloria/Class/Wallet/Model/VPPayTemplateItem.swift +++ b/Veloria/Class/Wallet/Model/VPPayTemplateItem.swift @@ -19,16 +19,16 @@ class VPPayTemplateItem: VPModel, SmartCodable { func getText() -> String { switch self { case .week: - return "Weekly VIP".localized + return "week".localized case .month: - return "Monthly VIP".localized + return "month".localized case .quarter: - return "Quarterly VIP".localized + return "quarter".localized case .year: - return "Yearly VIP".localized + return "year".localized } } } diff --git a/Veloria/Class/Wallet/View/VPCoinsBuyCell.swift b/Veloria/Class/Wallet/View/VPCoinsBuyCell.swift new file mode 100644 index 0000000..29dbb2b --- /dev/null +++ b/Veloria/Class/Wallet/View/VPCoinsBuyCell.swift @@ -0,0 +1,189 @@ +// +// VPCoinsBuyCell.swift +// Veloria +// +// Created by 湖南秦九 on 2025/5/30. +// + +import UIKit + +class VPCoinsBuyCell: VPCollectionViewCell { + + var item: VPPayTemplateItem? { + didSet { + coinCountLabel.text = "+\(item?.coins ?? 0)" + priceLabel.text = "\(item?.currency ?? "")\(item?.price ?? "0")" + + if let mark = item?.corner_marker, !mark.isEmpty { + hotBgView.isHidden = false + hotLabel.text = mark + } else { + hotBgView.isHidden = true + } + + if let sendCoins = item?.send_coins, sendCoins > 0, let coins = item?.coins { + sendBgView.isHidden = false + let percent = CGFloat(sendCoins) / CGFloat(coins) * 100 + + sendLabel.text = String(format: "+%.0f%%".localized, percent) + } else { + sendBgView.isHidden = true + } + } + } + + var vp_isSelected: Bool = false { + didSet { + if vp_isSelected { + self.bgView.isHidden = false + selectedImageView.isHidden = false + } else { + self.bgView.isHidden = true + selectedImageView.isHidden = true + } + } + } + + private lazy var bgView: VPGradientView = { + let view = VPGradientView() + view.vp_setGradientBorder() + view.colors = [UIColor.color05CEA0(alpha: 0.3).cgColor, UIColor.color7C174F(alpha: 0.3).cgColor] + view.locations = [0, 1] + view.startPoint = .init(x: 0, y: 0.3) + view.endPoint = .init(x: 1, y: 0.8) + return view + }() + + private lazy var selectedImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "selected_icon_01")) + return imageView + }() + + private lazy var coinCountLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 16) + label.textColor = .colorFFFFFF() + return label + }() + + private lazy var iconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "coin_icon_04")) + return imageView + }() + + private lazy var priceLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFFFFFF(alpha: 0.6) + return label + }() + + 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 + }() + + private lazy var sendBgView: UIView = { + let view = UIView() + view.backgroundColor = .color05CEA0() + view.addRadius(topLeft: 0, topRight: 8, bottomLeft: 8, bottomRight: 0) + view.layer.zPosition = 0 + return view + }() + + private lazy var sendLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 11) + label.textColor = .color00211A() + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + bgView.layer.cornerRadius = 8 + bgView.layer.masksToBounds = true + self.contentView.layer.cornerRadius = 8 + self.contentView.layer.masksToBounds = true + self.contentView.layer.borderColor = UIColor.colorFFFFFF(alpha: 0.25).cgColor + self.contentView.layer.borderWidth = 1 + + vp_setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension VPCoinsBuyCell { + + private func vp_setupUI() { + contentView.addSubview(bgView) + contentView.addSubview(selectedImageView) + contentView.addSubview(coinCountLabel) + contentView.addSubview(iconImageView) + contentView.addSubview(priceLabel) + contentView.addSubview(hotBgView) + hotBgView.addSubview(hotLabel) + contentView.addSubview(sendBgView) + sendBgView.addSubview(sendLabel) + + + bgView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + selectedImageView.snp.makeConstraints { make in + make.bottom.right.equalToSuperview() + } + + coinCountLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(22) + } + + iconImageView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(45) + } + + priceLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.bottom.equalToSuperview().offset(-11) + } + + 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) + } + + sendBgView.snp.makeConstraints { make in + make.right.top.equalToSuperview() + make.height.equalTo(16) + } + + sendLabel.snp.makeConstraints { make in + make.center.equalToSuperview() + make.left.equalToSuperview().offset(5) + } + + } + +} + diff --git a/Veloria/Class/Wallet/View/VPVipBuyCell.swift b/Veloria/Class/Wallet/View/VPVipBuyCell.swift index 5b7402b..5f27b3b 100644 --- a/Veloria/Class/Wallet/View/VPVipBuyCell.swift +++ b/Veloria/Class/Wallet/View/VPVipBuyCell.swift @@ -15,21 +15,41 @@ class VPVipBuyCell: VPCollectionViewCell { if let key = item?.vip_type_key?.rawValue { bgImageView.image = UIImage(named: "vip_buy_bg_\(key)") } - vipNameLabel.text = item?.vip_type_key?.getText() +// 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() ?? "")" + + if let coin = item?.send_coins, coin > 0 { + sendCoinBgView.isHidden = false + sendCoinView.isHidden = false + let text = String(format: "Extra %@".localized, "\(coin)") + sendCoinView.setTitle("+" + text, for: .normal) + } else { + sendCoinBgView.isHidden = true + sendCoinView.isHidden = true + } 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) 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) case .year: colors = [UIColor.color9C6586().cgColor, UIColor.color57314F().cgColor] + sendCoinBgView.colors = [UIColor.colorFFD8F5().cgColor, UIColor.colorFFD8F5(alpha: 0).cgColor] + sendCoinView.setTitleColor(.color674162(), for: .normal) default: break } @@ -39,6 +59,13 @@ class VPVipBuyCell: VPCollectionViewCell { unitLabel.gradientLayer.colors = colors moneyLabel.gradientLayer.colors = colors durationLabel.gradientLayer.colors = colors + durationLabel.gradientLayer.colors = colors + } + } + + var vp_isSelected = false { + didSet { + selectedImageView.isHidden = !vp_isSelected } } @@ -71,6 +98,31 @@ class VPVipBuyCell: VPCollectionViewCell { return label }() + private lazy var sendCoinBgView: 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 = 6 + view.layer.masksToBounds = true + return view + }() + + private lazy var sendCoinView: UIButton = { + let view = JXButton(type: .custom) + view.isUserInteractionEnabled = false + view.titleDirection = .left + view.space = 4 + view.jx_font = .fontRegular(ofSize: 12) + view.setImage(UIImage(named: "coin_icon_02"), for: .normal) + return view + }() + + private lazy var selectedImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "selected_icon_01")) + return imageView + }() + override init(frame: CGRect) { super.init(frame: frame) @@ -80,6 +132,7 @@ class VPVipBuyCell: VPCollectionViewCell { @MainActor required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + } extension VPVipBuyCell { @@ -89,6 +142,10 @@ extension VPVipBuyCell { contentView.addSubview(vipNameLabel) contentView.addSubview(unitLabel) contentView.addSubview(moneyLabel) + contentView.addSubview(durationLabel) + contentView.addSubview(sendCoinBgView) + contentView.addSubview(sendCoinView) + contentView.addSubview(selectedImageView) bgImageView.snp.makeConstraints { make in make.edges.equalToSuperview() @@ -96,19 +153,42 @@ extension VPVipBuyCell { vipNameLabel.snp.makeConstraints { make in make.left.equalToSuperview().offset(14) - make.top.equalToSuperview().offset(31) + make.top.equalToSuperview().offset(35) make.height.equalTo(22) } unitLabel.snp.makeConstraints { make in make.left.equalTo(vipNameLabel) - make.top.equalTo(vipNameLabel.snp.bottom).offset(20) + make.top.equalTo(vipNameLabel.snp.bottom).offset(17) make.height.equalTo(20) } moneyLabel.snp.makeConstraints { make in make.left.equalTo(unitLabel.snp.right) - make.bottom.equalTo(unitLabel).offset(-1) + make.bottom.equalTo(unitLabel) + } + + durationLabel.snp.makeConstraints { make in + make.bottom.equalTo(moneyLabel).offset(-2) + make.left.equalTo(moneyLabel.snp.right) + make.height.equalTo(20) + } + + sendCoinBgView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(14) + make.bottom.equalToSuperview().offset(-10) + make.height.equalTo(24) + make.width.equalTo(105) + } + + sendCoinView.snp.makeConstraints { make in + make.centerY.equalTo(sendCoinBgView) + make.left.equalTo(sendCoinBgView).offset(11) + } + + selectedImageView.snp.makeConstraints { make in + make.left.equalToSuperview() + make.top.equalToSuperview().offset(18) } } diff --git a/Veloria/Libs/User/VPUserInfo.swift b/Veloria/Libs/User/VPUserInfo.swift index 32a5c8a..7b4ac0f 100644 --- a/Veloria/Libs/User/VPUserInfo.swift +++ b/Veloria/Libs/User/VPUserInfo.swift @@ -35,6 +35,10 @@ class VPUserInfo: VPModel, SmartCodable, NSSecureCoding { var country: String? + var totalCoin: Int { + return (coin_left_total ?? 0) + (send_coin_left_total ?? 0) + } + required init() { } static var supportsSecureCoding: Bool { diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/Contents.json b/Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/Contents.json new file mode 100644 index 0000000..c18e822 --- /dev/null +++ b/Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "金币1 2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "金币1 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/金币1 2@2x.png b/Veloria/Source/Assets.xcassets/icon/coin_icon_02.imageset/金币1 2@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..620ef11251f21362c47134b7a07db77a7c1eb35d GIT binary patch literal 2453 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 B`au8y literal 0 HcmV?d00001 diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/Contents.json b/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/Contents.json new file mode 100644 index 0000000..e197cfa --- /dev/null +++ b/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "金币 2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "金币 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/金币 2@2x.png b/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/金币 2@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d51924cc8aa9bee81541c17b69a5aee8a25b173 GIT binary patch literal 4092 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 literal 0 HcmV?d00001 diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/金币 2@3x.png b/Veloria/Source/Assets.xcassets/icon/coin_icon_03.imageset/金币 2@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..64e0e059b43b1946b4234fa3685482c91680b0e7 GIT binary patch literal 8047 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 literal 0 HcmV?d00001 diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/Contents.json b/Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/Contents.json new file mode 100644 index 0000000..8b03fba --- /dev/null +++ b/Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "金币1 3@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "金币1 3@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/金币1 3@2x.png b/Veloria/Source/Assets.xcassets/icon/coin_icon_04.imageset/金币1 3@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6325fc18462f4adea12891459b8fc12cec299d GIT binary patch literal 5726 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 literal 0 HcmV?d00001 diff --git a/Veloria/Source/Assets.xcassets/icon/selected_icon_01.imageset/Component 63@2x.png b/Veloria/Source/Assets.xcassets/icon/selected_icon_01.imageset/Component 63@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9fec237012f7dc647c8354e62630be597f838f2a GIT binary patch literal 740 zcmV)LGh#|lNQU+%TV(dVMPB`h96=s^PMMz0D#F9iTY&8pHtk{r{VChJmZfry> zAZ3V=7#KkE1hj%&-*ZySP2JW>?5pihy7=A2R{ZI`yWA;Q5EGB}G5)VmcuxWNnxD2< zqs()&i6#jhGz3Hw36S$6knluwzb$|!63)58CLVD{J4k3oXE{^Y#O78Svg*ZGm`hk- z{~d)oQbyKqP~gDCWaUjA>g)iQF)7DJHmBWiT38$t{(z13IL+BYqk`4ZGpAi$DIg47 zVG|pg0;P?ZptWl#84uikPP>jU@MKtJSq(9OWs9Af+qb$q`1$@b!oXRjIlBVN2r{r&CQ@OB#k|szWjVXu3VN2?kFun_@FD)6 z{fF9b$bz=aFV@gIwu_8p(elIDoJd6(tl`y(Epy~0eL?gUT&nneAuYqQ@GE04Y09uo zi&5(=Stb?2oK*#vi!^7A^X^S@N!u){B4<=#*g+pkiZBat$quL__b8_W`fu%H0S*Da W2le~mT8g>=0000#)PsNm(sNrY7m z$||H_%Xm;HN!+6xtZYI`t_#Z%onPqwMl~P;N!@f=d59%z*iS;=qDdOz*oZFVW0tH! z(l9keOUd?8b1~H5c?Bui7EDDaF}FmjU6+%)d}nZeau_}8IXH=7>Uf86NXhS$T}9u_ zH4Mh5blH2EU2F#8`qc@%l@pwok(ca)i(tt^Yt!)boYKcEJNNSsvZ-x2fkEod zmCRp3@7_^Z-$sk!N^E@d;r~yjAHEZ_@5c))S^pZ|e4qIsffmyr3F55(N@?t)d(KG_K{^NoJ(z2H}NI!D))*c-G4E zLKQ3>LY8(9G1^_!)%BF3>mx<^cs6JuRa7EHTZ092A(BFaNYS-vT5u65x|$R%bQ>P@ y#H}uLRyfI`GqgS9g)L3TO