充值页面UI开发

This commit is contained in:
zjx 2025-05-30 13:33:48 +08:00
parent 83d41497ec
commit cbac290cf7
26 changed files with 709 additions and 36 deletions

View File

@ -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 = "<group>"; };
BFF5AFC12DE837FC0044227A /* VPPayTemplateItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayTemplateItem.swift; sourceTree = "<group>"; };
BFF5AFC32DE84F9C0044227A /* Aa厚底黑.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Aa厚底黑.ttf"; sourceTree = "<group>"; };
BFF5AFC52DE863C00044227A /* VPGradientButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPGradientButton.swift; sourceTree = "<group>"; };
BFF5AFC72DE9473B0044227A /* VPCoinsBuyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPCoinsBuyCell.swift; sourceTree = "<group>"; };
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 = "<group>"; };
/* 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 = "<group>";
@ -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 */,

View File

@ -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

View File

@ -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)
}
}

View File

@ -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)

View File

@ -76,7 +76,7 @@ class VPNetwork: NSObject {
var res = VPNetworkResponse<T>()
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<T>()
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<T>()
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<T>()
response.code = -1
response.msg = "movia_error".localized
response.msg = "Error".localized
return response
}
}

View File

@ -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
}
}
}

View File

@ -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()
}
}

View File

@ -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()
}
*/
}

View File

@ -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()
}
}
}

View File

@ -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
}
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

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

View File

@ -47,7 +47,14 @@
"Membership Benefits" = "Membership Benefits";
"1 week" = "1 week";
"8 days" = "8 days";
"Weekly VIP" = "Weekly VIP";
"week" = "week";
"month" = "month";
"quarter" = "quarter";
"year" = "year";
"Error" = "Error";
"Extra %@" = "Extra %@";
"Get More Coins" = "Get More Coins";
"Coins: %@" = "Coins: %@";
"kHomeTitleText" = "10,000+ addictive shorts await!";
@ -61,6 +68,15 @@
"kVipPrivilegeText4" = "Unlimited access to all series for %@ (No Ads)";
"kVipPrivilegeText5" = "The donate coins will expire in %@";
"kVipPrivilegeText6" = "Auto renew, cancel anytime";
//无网提示
"kNetworkToast01" = "The service is abnormal. Check the network.";
"kStoreTips" = "1. Coins are virtual items and cannot be refunded. Use it for this product.
2. Gold coins will never expire, the reward coins will expire 24 hours a day.
3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.
4. The purchase has not been credited, click <Restore> torefresh.
5. For other questions, contact us via Profile>Help &feedback.";
//请选择需要删除的短剧
"kToastText1" = "Please select the short plays that need to be deleted";