761 lines
26 KiB
Swift
761 lines
26 KiB
Swift
//
|
||
// VIPSubscribeSheet.swift
|
||
// Crush
|
||
//
|
||
// Created by Leon on 2025/9/16.
|
||
//
|
||
|
||
class VIPSubscribeSheet: EGPopBaseView {
|
||
var bgImageView: AutoRatioImageView!
|
||
|
||
var titleLabel: UILabel!
|
||
var closeButton: EPIconTertiaryButton!
|
||
|
||
var privilegesContainer: UIView!
|
||
var effectView: UIVisualEffectView!
|
||
var layout = UICollectionViewFlowLayout()
|
||
var cv: UICollectionView!
|
||
var leftButton: EPIconTertiaryDarkButton!
|
||
var rightButton: EPIconTertiaryDarkButton!
|
||
|
||
var agreenmentContainer: UIView!
|
||
|
||
var operateButton: StyleButton!
|
||
|
||
var tableView: UITableView!
|
||
|
||
// MARK: - Data Properties
|
||
private var vipProducts: [VIPSubcribeProduct] = []
|
||
private var privileges: [MemberPrivDict] = []
|
||
private var currentRealCvIndex = 0
|
||
/// 0~10
|
||
private var currentPrivilegeIndex = 0
|
||
private var selectedProductIndex = 0
|
||
private var multiplier = 100 // 用于无限循环的倍数
|
||
private var initialScrollCompleted = false // 标记是否已完成初始滚动
|
||
|
||
init() {
|
||
super.init(direction: .bottom)
|
||
|
||
contentView.backgroundColor = .c.csbn
|
||
contentLength = 693 + UIWindow.safeAreaBottom
|
||
|
||
setupViews()
|
||
setupData()
|
||
setupEvent()
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
// MARK: - Data
|
||
private func setupData(){
|
||
|
||
// Group load Hud
|
||
Hud.showIndicator()
|
||
|
||
let group = DispatchGroup()
|
||
group.enter()
|
||
CLPurchase.shared.loadVIPTiersProducts { [weak self] products in
|
||
group.leave()
|
||
// 配置tableView中,充值档位
|
||
if let products = products {
|
||
self?.vipProducts = products
|
||
DispatchQueue.main.async {
|
||
self?.tableView.reloadData()
|
||
}
|
||
}
|
||
}
|
||
|
||
group.enter()
|
||
CLPurchase.shared.loadCurrentUserVipDetail { [weak self] output in
|
||
group.leave()
|
||
// get output.memberPrivList 权限展示列表,并显示在cv中
|
||
if let output = output, let privileges = output.memberPrivList {
|
||
self?.privileges = privileges
|
||
DispatchQueue.main.async {
|
||
self?.cv.reloadData()
|
||
self?.updateNavigationButtons()
|
||
self?.initialScrollToMiddle() // 初始化时滚动到中间位置
|
||
}
|
||
}
|
||
}
|
||
|
||
group.notify(queue: .main) {
|
||
// 所有 enter/leave 成对后,回调执行
|
||
print("All completed")
|
||
Hud.hideIndicator()
|
||
}
|
||
}
|
||
|
||
private func setupEvent(){
|
||
NotificationCenter.default.addObserver(self, selector: #selector(notifyVIPChanged(_:)), name: AppNotificationName.vipStateChange.notificationName, object: nil)
|
||
}
|
||
|
||
@objc private func notifyVIPChanged(_ noti: Notification){
|
||
dismiss()
|
||
}
|
||
|
||
// MARK: - Functions
|
||
private func updateNavigationButtons() {
|
||
leftButton.isHidden = privileges.count <= 1
|
||
rightButton.isHidden = privileges.count <= 1
|
||
}
|
||
|
||
private func scrollToPrivilege(at index: Int) {
|
||
guard index >= 0 && index < privileges.count else { return }
|
||
currentPrivilegeIndex = index
|
||
|
||
// 计算当前应该滚动到的位置
|
||
let totalItems = privileges.count * multiplier
|
||
let middleStart = (totalItems / 2) - (totalItems / 2) % privileges.count
|
||
let targetIndex = middleStart + index
|
||
currentRealCvIndex = targetIndex
|
||
let indexPath = IndexPath(item: targetIndex, section: 0)
|
||
cv.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
|
||
}
|
||
|
||
private func initialScrollToMiddle() {
|
||
guard privileges.count > 0 && !initialScrollCompleted else { return }
|
||
let totalItems = privileges.count * multiplier
|
||
let middleStart = (totalItems / 2) - (totalItems / 2) % privileges.count
|
||
currentRealCvIndex = middleStart
|
||
let indexPath = IndexPath(item: middleStart, section: 0)
|
||
|
||
DispatchQueue.main.async {
|
||
self.cv.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
|
||
self.initialScrollCompleted = true
|
||
}
|
||
}
|
||
|
||
// MARK: - Action
|
||
|
||
@objc private func leftButtonPressed() {
|
||
guard privileges.count > 0 else { return }
|
||
|
||
// 计算下一个目标位置(相邻位置)
|
||
let nextRealIndex = currentRealCvIndex - 1
|
||
|
||
// 检查是否需要边界处理
|
||
let totalItems = privileges.count * multiplier
|
||
let middleStart = (totalItems / 2) - (totalItems / 2) % privileges.count
|
||
|
||
if nextRealIndex < 0 {
|
||
// 如果超出左边界,跳转到右侧对应位置
|
||
let targetIndex = totalItems - 1
|
||
currentRealCvIndex = targetIndex
|
||
currentPrivilegeIndex = targetIndex % privileges.count
|
||
let indexPath = IndexPath(item: targetIndex, section: 0)
|
||
cv.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
|
||
} else {
|
||
// 正常向左切换
|
||
currentRealCvIndex = nextRealIndex
|
||
currentPrivilegeIndex = nextRealIndex % privileges.count
|
||
let indexPath = IndexPath(item: nextRealIndex, section: 0)
|
||
cv.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
|
||
}
|
||
}
|
||
|
||
@objc private func rightButtonPressed() {
|
||
guard privileges.count > 0 else { return }
|
||
|
||
// 计算下一个目标位置(相邻位置)
|
||
let nextRealIndex = currentRealCvIndex + 1
|
||
|
||
// 检查是否需要边界处理
|
||
let totalItems = privileges.count * multiplier
|
||
|
||
if nextRealIndex >= totalItems {
|
||
// 如果超出右边界,跳转到左侧对应位置
|
||
let targetIndex = 0
|
||
currentRealCvIndex = targetIndex
|
||
currentPrivilegeIndex = targetIndex % privileges.count
|
||
let indexPath = IndexPath(item: targetIndex, section: 0)
|
||
cv.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
|
||
} else {
|
||
// 正常向右切换
|
||
currentRealCvIndex = nextRealIndex
|
||
currentPrivilegeIndex = nextRealIndex % privileges.count
|
||
let indexPath = IndexPath(item: nextRealIndex, section: 0)
|
||
cv.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
|
||
}
|
||
}
|
||
|
||
@objc private func termsOfServicePressed() {
|
||
AppRouter.goTermsOfService()
|
||
dismiss()
|
||
}
|
||
|
||
@objc private func privacyPolicyPressed() {
|
||
AppRouter.goPrivacyPolicy()
|
||
dismiss()
|
||
}
|
||
|
||
@objc private func tapBottomButton() {
|
||
// 开始续期订阅...
|
||
guard selectedProductIndex < vipProducts.count else { return }
|
||
let selectedProduct = vipProducts[selectedProductIndex]
|
||
print("选择的产品: \(selectedProduct.productId ?? "")")
|
||
|
||
guard let productId = selectedProduct.productId, let payment = selectedProduct.payAmount else{
|
||
return
|
||
}
|
||
|
||
let product = IAPProducts()
|
||
product.productId = productId
|
||
product.chargeAmount = payment
|
||
|
||
IAPCore.shared.requestProducts([product]) {iapIds in
|
||
if iapIds.count > 0 {
|
||
let tradeId = String.randomNumber(length: 10)
|
||
IAPCore.shared.addPayProductId(productId: productId, tradeId: tradeId)
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
// MARK: - UI
|
||
private func setupViews() {
|
||
bgImageView = {
|
||
let v = AutoRatioImageView()
|
||
v.setImage(UIImage(named: "vip_sheet_bg"))
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.top.leading.trailing.equalToSuperview()
|
||
}
|
||
return v
|
||
}()
|
||
|
||
closeButton = {
|
||
let v = EPIconTertiaryButton(radius: .round, iconSize: .small, iconCode: .delete)
|
||
v.addTarget(self, action: #selector(bgButtonPressed), for: .touchUpInside)
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.top.equalToSuperview().offset(20)
|
||
make.size.equalTo(v.bgImageSize())
|
||
make.trailing.equalToSuperview().offset(-16)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
titleLabel = {
|
||
let v = UILabel()
|
||
v.font = .t.ttm
|
||
v.textColor = .text
|
||
v.textAlignment = .center
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(24)
|
||
make.trailing.equalToSuperview().offset(-24)
|
||
make.top.equalToSuperview().offset(24)
|
||
}
|
||
v.text = "Crushlevel VIP"
|
||
return v
|
||
}()
|
||
|
||
setupPrivilegeView()
|
||
|
||
setupAgreementsView()
|
||
|
||
operateButton = {
|
||
let v = StyleButton()
|
||
v.primary(size: .large)
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(CGFloat.lrs)
|
||
make.trailing.equalToSuperview().offset(-CGFloat.lrs)
|
||
make.bottom.equalTo(agreenmentContainer.snp.top).offset(-16)
|
||
}
|
||
v.addTarget(self, action: #selector(tapBottomButton), for: .touchUpInside)
|
||
v.setTitle("Subscribe", for: .normal)
|
||
return v
|
||
}()
|
||
|
||
setupVIPSubscribeItemsView()
|
||
}
|
||
|
||
private func setupPrivilegeView() {
|
||
privilegesContainer = {
|
||
let v = UIView()
|
||
v.cornerRadius = 12
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(CGFloat.lrs)
|
||
make.trailing.equalToSuperview().offset(-CGFloat.lrs)
|
||
make.top.equalToSuperview().offset(64)
|
||
make.height.equalTo(229)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
effectView = {
|
||
let v = UIVisualEffectView(effect: UIBlurEffect(style: .light))
|
||
v.alpha = 0.9
|
||
privilegesContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
return v
|
||
}()
|
||
|
||
// cv is in privilegesContainer, cellwidth and height is same as privilegesContainer. pageEnable = true, scroll hori..
|
||
cv = {
|
||
layout.scrollDirection = .horizontal
|
||
let width = UIScreen.width - 24 * 2
|
||
layout.itemSize = CGSize(width: width, height: 229)
|
||
layout.minimumLineSpacing = 0
|
||
layout.minimumInteritemSpacing = 0
|
||
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
|
||
|
||
let v = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
|
||
v.backgroundColor = .clear
|
||
v.register(VIPPrivilegeGridCell.self, forCellWithReuseIdentifier: "VIPPrivilegeGridCell")
|
||
v.delegate = self
|
||
v.dataSource = self
|
||
v.isPagingEnabled = true
|
||
v.showsHorizontalScrollIndicator = false
|
||
privilegesContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.edges.equalToSuperview()
|
||
}
|
||
return v
|
||
}()
|
||
|
||
leftButton = {
|
||
let v = EPIconTertiaryDarkButton(radius: .round, iconSize: .xs, iconCode: .arrowLeftBorder)
|
||
privilegesContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.top.equalToSuperview().offset(58.5)
|
||
make.leading.equalToSuperview().offset(16)
|
||
make.size.equalTo(v.bgImageSize())
|
||
}
|
||
return v
|
||
}()
|
||
|
||
rightButton = {
|
||
let v = EPIconTertiaryDarkButton(radius: .round, iconSize: .xs, iconCode: .arrowRightBorder)
|
||
privilegesContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.top.equalToSuperview().offset(58.5)
|
||
make.trailing.equalToSuperview().offset(-16)
|
||
make.size.equalTo(v.bgImageSize())
|
||
}
|
||
return v
|
||
}()
|
||
|
||
leftButton.addTarget(self, action: #selector(leftButtonPressed), for: .touchUpInside)
|
||
rightButton.addTarget(self, action: #selector(rightButtonPressed), for: .touchUpInside)
|
||
}
|
||
|
||
private func setupAgreementsView() {
|
||
agreenmentContainer = {
|
||
let v = UIView()
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.height.equalTo(32)
|
||
make.leading.equalToSuperview()
|
||
make.trailing.equalToSuperview()
|
||
make.bottom.equalToSuperview().offset(-UIWindow.safeAreaBottom)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
let line = {
|
||
let v = CLLine()
|
||
agreenmentContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.center.equalToSuperview()
|
||
make.size.equalTo(CGSize(width: 1, height: 8))
|
||
}
|
||
return v
|
||
}()
|
||
|
||
let leftButton = {
|
||
let v = UIButton()
|
||
v.titleLabel?.font = UIFont.t.tls
|
||
v.setTitleColor(.c.ctsn, for: .normal)
|
||
agreenmentContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.trailing.equalTo(line.snp.leading).offset(-16)
|
||
make.top.bottom.equalToSuperview()
|
||
}
|
||
v.addTarget(self, action: #selector(termsOfServicePressed), for: .touchUpInside)
|
||
return v
|
||
}()
|
||
|
||
let rightButton = {
|
||
let v = UIButton()
|
||
v.titleLabel?.font = UIFont.t.tls
|
||
v.setTitleColor(.c.ctsn, for: .normal)
|
||
agreenmentContainer.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalTo(line.snp.trailing).offset(16)
|
||
make.top.bottom.equalToSuperview()
|
||
}
|
||
v.addTarget(self, action: #selector(privacyPolicyPressed), for: .touchUpInside)
|
||
return v
|
||
}()
|
||
|
||
leftButton.setTitle("Terms of Service", for: .normal)
|
||
rightButton.setTitle("Privacy Policy", for: .normal)
|
||
}
|
||
|
||
private func setupVIPSubscribeItemsView() {
|
||
tableView = {
|
||
let v = UITableView()
|
||
v.backgroundColor = .clear
|
||
v.register(VIPTierListCell.self, forCellReuseIdentifier: "VIPTierListCell")
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview()
|
||
make.trailing.equalToSuperview()
|
||
make.top.equalTo(privilegesContainer.snp.bottom).offset(16)
|
||
make.bottom.equalTo(operateButton.snp.top).offset(-16)
|
||
}
|
||
return v
|
||
}()
|
||
tableView.delegate = self
|
||
tableView.dataSource = self
|
||
}
|
||
|
||
}
|
||
|
||
extension VIPSubscribeSheet: UICollectionViewDelegate, UICollectionViewDataSource {
|
||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||
return privileges.count * multiplier
|
||
}
|
||
|
||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "VIPPrivilegeGridCell", for: indexPath) as! VIPPrivilegeGridCell
|
||
|
||
let actualIndex = indexPath.item % privileges.count
|
||
if actualIndex < privileges.count {
|
||
let privilege = privileges[actualIndex]
|
||
cell.configure(with: privilege)
|
||
}
|
||
|
||
return cell
|
||
}
|
||
|
||
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
|
||
// 更新当前索引
|
||
let pageWidth = scrollView.frame.width
|
||
let currentPage = Int(scrollView.contentOffset.x / pageWidth)
|
||
currentRealCvIndex = currentPage
|
||
currentPrivilegeIndex = currentPage % privileges.count
|
||
|
||
// 实现无限循环:当接近边界时,跳转到中间位置
|
||
let totalItems = privileges.count * multiplier
|
||
let middleStart = (totalItems / 2) - (totalItems / 2) % privileges.count
|
||
|
||
if currentPage < privileges.count {
|
||
// 接近开始位置,跳转到中间偏后位置
|
||
let targetIndex = middleStart + currentPrivilegeIndex
|
||
let targetIndexPath = IndexPath(item: targetIndex, section: 0)
|
||
DispatchQueue.main.async {
|
||
self.cv.scrollToItem(at: targetIndexPath, at: .centeredHorizontally, animated: false)
|
||
}
|
||
} else if currentPage >= totalItems - privileges.count {
|
||
// 接近结束位置,跳转到中间偏前位置
|
||
let targetIndex = middleStart - (privileges.count - currentPrivilegeIndex)
|
||
let targetIndexPath = IndexPath(item: targetIndex, section: 0)
|
||
DispatchQueue.main.async {
|
||
self.cv.scrollToItem(at: targetIndexPath, at: .centeredHorizontally, animated: false)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
extension VIPSubscribeSheet: UITableViewDelegate, UITableViewDataSource {
|
||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||
return vipProducts.count
|
||
}
|
||
|
||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||
let cell = tableView.dequeueReusableCell(withIdentifier: "VIPTierListCell", for: indexPath) as! VIPTierListCell
|
||
|
||
if indexPath.row < vipProducts.count {
|
||
let product = vipProducts[indexPath.row]
|
||
cell.configure(with: product)
|
||
cell.setupSelected(selected: indexPath.row == selectedProductIndex)
|
||
}
|
||
|
||
return cell
|
||
}
|
||
|
||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||
print("didSelectRowAt \(indexPath)")
|
||
selectedProductIndex = indexPath.row
|
||
tableView.reloadData()
|
||
}
|
||
}
|
||
|
||
class VIPPrivilegeGridCell: UICollectionViewCell {
|
||
var icon: UIImageView!
|
||
var titleLabel: CLLabel!
|
||
var descLabel: LineSpaceLabel!
|
||
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
setupViews()
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
private func setupViews() {
|
||
backgroundColor = .clear
|
||
icon = {
|
||
let v = UIImageView()
|
||
v.cornerRadius = 8
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.size.equalTo(CGSize(width: 140, height: 93))
|
||
make.top.equalToSuperview().offset(24)
|
||
make.centerX.equalToSuperview()
|
||
}
|
||
return v
|
||
}()
|
||
|
||
titleLabel = {
|
||
let v = CLLabel()
|
||
v.font = .t.tts
|
||
v.textAlignment = .center
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(16)
|
||
make.trailing.equalToSuperview().offset(-16)
|
||
make.top.equalTo(icon.snp.bottom).offset(16)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
descLabel = {
|
||
let v = LineSpaceLabel()
|
||
let typo = CLSystemToken.typography(token: .tls)
|
||
v.textColor = .text
|
||
v.textAlignment = .center
|
||
v.config(typo)
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(16)
|
||
make.trailing.equalToSuperview().offset(-16)
|
||
make.top.equalTo(titleLabel.snp.bottom).offset(8)
|
||
}
|
||
return v
|
||
}()
|
||
}
|
||
|
||
func configure(with privilege: MemberPrivDict) {
|
||
titleLabel.text = privilege.title ?? ""
|
||
descLabel.text = privilege.desc ?? ""
|
||
|
||
// 设置图片
|
||
if let imgUrl = privilege.img, !imgUrl.isEmpty {
|
||
// 使用网络图片加载
|
||
icon.loadImage(imgUrl, bgColor: .clear)
|
||
} else {
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
class VIPTierListCell: UITableViewCell {
|
||
var blockView: UIView!
|
||
var checkButton: EPRadioButton!
|
||
var coinAndLabel: CLIconLabel!
|
||
|
||
var periodLabel: CLLabel!
|
||
var descLabel: CLLabel!
|
||
|
||
var gradientFlag: GradientView!
|
||
var discountLabelOnFlag: CLLabel!
|
||
|
||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||
|
||
selectionStyle = .none
|
||
backgroundColor = .clear
|
||
|
||
setupViews()
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
private func setupViews() {
|
||
blockView = {
|
||
let v = UIView()
|
||
v.backgroundColor = .c.csnn
|
||
v.cornerRadius = 12
|
||
v.layer.borderWidth = 0
|
||
v.layer.borderColor = UIColor.c.cpn.cgColor
|
||
contentView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.leading.equalToSuperview().offset(CGFloat.lrs)
|
||
make.trailing.equalToSuperview().offset(-CGFloat.lrs)
|
||
make.top.equalToSuperview()
|
||
make.bottom.equalToSuperview().offset(-12)
|
||
make.height.equalTo(80)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
checkButton = {
|
||
let v = EPRadioButton()
|
||
v.setupRadioStyle(.checkEmpty)
|
||
v.isUserInteractionEnabled = false
|
||
blockView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.trailing.equalToSuperview().offset(-24)
|
||
make.centerY.equalToSuperview()
|
||
}
|
||
return v
|
||
}()
|
||
|
||
coinAndLabel = {
|
||
let v = CLIconLabel()
|
||
v.iconSize = CGSize(width: 16, height: 16)
|
||
//v.iconImageView.image = UIImage(named: "icon_16_diamond")
|
||
v.iconImageView.isHidden = true
|
||
v.contentLabel.textColor = .text
|
||
v.contentLabel.font = .t.tnmm
|
||
blockView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.centerY.equalToSuperview()
|
||
make.trailing.equalTo(checkButton.snp.leading).offset(-8)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
periodLabel = {
|
||
let v = CLLabel()
|
||
v.font = .t.tts
|
||
v.textColor = .text
|
||
blockView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.centerY.equalToSuperview()
|
||
make.leading.equalToSuperview().offset(24)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
descLabel = {
|
||
let v = CLLabel()
|
||
v.font = .t.tls
|
||
v.textColor = .c.ctsn
|
||
blockView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.lastBaseline.equalTo(periodLabel)
|
||
make.leading.equalTo(periodLabel.snp.trailing).offset(4)
|
||
}
|
||
return v
|
||
}()
|
||
|
||
gradientFlag = {
|
||
let gradient = CLSystemToken.gradient(token: .ccvn)
|
||
let v = GradientView(colors: gradient.colors(), gradientType: .leftToRight)
|
||
v.cornerRadius = 12
|
||
v.backgroundColor = .c.csnn
|
||
v.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner]
|
||
blockView.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.height.equalTo(24)
|
||
make.leading.top.equalToSuperview()
|
||
}
|
||
return v
|
||
}()
|
||
|
||
discountLabelOnFlag = {
|
||
let v = CLLabel()
|
||
v.font = .t.tbss
|
||
v.textColor = .c.cbd
|
||
gradientFlag.addSubview(v)
|
||
v.snp.makeConstraints { make in
|
||
make.centerY.equalToSuperview()
|
||
make.leading.equalToSuperview().offset(8)
|
||
make.trailing.equalToSuperview().offset(-8)
|
||
}
|
||
return v
|
||
}()
|
||
}
|
||
|
||
func configure(with product: VIPSubcribeProduct) {
|
||
// 设置价格
|
||
// if let chargeAmount = product.chargeAmount {
|
||
// let coin = Coin(cents: chargeAmount)
|
||
// coinAndLabel.contentLabel.text = coin.formatted
|
||
// }
|
||
|
||
let period = product.period ?? .month
|
||
|
||
// 设置周期
|
||
let periodText = getPeriodText(from: product.period)
|
||
periodLabel.text = periodText
|
||
|
||
// 设置描述价格
|
||
if let payAmount = product.payAmount {
|
||
let price = Coin(cents: payAmount)
|
||
|
||
if period == .month{
|
||
descLabel.isHidden = true
|
||
}else if period == .season{
|
||
descLabel.isHidden = false
|
||
let pricePerMonth = CGFloat(payAmount) / 3.0
|
||
let pricePerMonthCoin = Coin(cents: Int(pricePerMonth))
|
||
descLabel.text = "$\(pricePerMonthCoin.formatted)/\(getPeriodShortText(from: product.period))"
|
||
}else if period == .year{
|
||
descLabel.isHidden = false
|
||
let pricePerMonth = CGFloat(payAmount) / 12.0
|
||
let pricePerMonthCoin = Coin(cents: Int(pricePerMonth))
|
||
descLabel.text = "$\(pricePerMonthCoin.formatted)/\(getPeriodShortText(from: product.period))"
|
||
}
|
||
// CrushCoin
|
||
coinAndLabel.contentLabel.text = "$\(price.formatted)"
|
||
}
|
||
|
||
// 设置折扣标签
|
||
if let discount = product.discount, let discountFloat = Float(discount), discountFloat > 0 {
|
||
gradientFlag.isHidden = false
|
||
discountLabelOnFlag.text = "\(discount)% Off"
|
||
} else {
|
||
gradientFlag.isHidden = true
|
||
}
|
||
}
|
||
|
||
private func getPeriodText(from period: PriceType?) -> String {
|
||
switch period {
|
||
case .month:
|
||
return "1 Month"
|
||
case .season:
|
||
return "3 Months"
|
||
case .year:
|
||
return "1 Year"
|
||
case .none:
|
||
return "1 Month"
|
||
}
|
||
}
|
||
|
||
private func getPeriodShortText(from period: PriceType?) -> String {
|
||
switch period {
|
||
case .month:
|
||
return "Month"
|
||
case .season:
|
||
return "Months"
|
||
case .year:
|
||
return "Year"
|
||
case .none:
|
||
return "Month"
|
||
}
|
||
}
|
||
|
||
func setupSelected(selected: Bool) {
|
||
checkButton.isSelected = selected
|
||
blockView.layer.borderWidth = selected ? 2 : 0
|
||
}
|
||
}
|