推荐增加播放功能,VIP弹窗
This commit is contained in:
parent
ff3f5a8f51
commit
1dd0094b1b
41
Apple账号资料.txt
Normal file
41
Apple账号资料.txt
Normal file
@ -0,0 +1,41 @@
|
||||
Thimra 开发者账号信息
|
||||
认证人 :陈佳
|
||||
认证设备 :Mac min
|
||||
设备型号 :MU9D3CH/A
|
||||
序列号 :TVJJ97WWHH
|
||||
手机号码 :190 7319 2960
|
||||
|
||||
企业邮箱 :thimra@thimratv.com 密码:9oldpGT_y0qR
|
||||
D-U-N-S:457012112
|
||||
公司主体 :Changsha Jiaer Network Technology Co., Ltd.
|
||||
公司地址 :Room 15006, Xijing Commercial Plaza, No. 383 Jinxing Middle Road
|
||||
官网 :https://www.thimratv.com
|
||||
appleId :cs.jiaer.developer@icloud.com
|
||||
密码 :Discover2024
|
||||
|
||||
|
||||
|
||||
账户持有人:
|
||||
Hong Kong Qin Jiu Media Culture Co., Limited
|
||||
银行账号:
|
||||
9558851001034420709
|
||||
复制
|
||||
币种:
|
||||
USD
|
||||
费率:
|
||||
0.7%
|
||||
银行名称:
|
||||
Industrial And Commercial Bank Of China Shanghai Pilot Free Trade Zone Branch Xinling Road Sub-Branch
|
||||
Swift Code:
|
||||
ICBKCNBJSHI
|
||||
CNAPS代码
|
||||
102290019237
|
||||
银行所在国家/地区:
|
||||
China
|
||||
银行地址:
|
||||
NO.118 Xinling Rd Shanghai Branch
|
||||
|
||||
|
||||
沙盒账号:
|
||||
jiaer@test.com
|
||||
Cje12345
|
@ -40,15 +40,6 @@ extension AppDelegate {
|
||||
private func showApnsAlert() {
|
||||
let view = SPApnsAlertView()
|
||||
view.show()
|
||||
|
||||
// let alert = UIAlertController(title: nil, message: "kAlertMessage_03".localized, preferredStyle: .alert)
|
||||
// alert.addAction(UIAlertAction(title: "movia_affirm".localized, style: .default, handler: { _ in
|
||||
// SPAPPTool.openApnsSetting()
|
||||
// }))
|
||||
// alert.addAction(UIAlertAction(title: "movia_Cancel".localized, style: .cancel))
|
||||
//
|
||||
//
|
||||
// SPAPPTool.topViewController()?.present(alert, animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
@ -83,11 +74,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
|
||||
SPStatAPI.requestStatApns(messageId: model.message_id ?? "", title: response.notification.request.content.title)
|
||||
|
||||
|
||||
if let shortPlayId = model.short_play_id {
|
||||
|
||||
if model.path == .videoDetail, let shortPlayId = model.short_play_id {
|
||||
let vc = SPPlayerDetailViewController()
|
||||
vc.shortPlayId = shortPlayId
|
||||
SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
} else if model.path == .promotion {
|
||||
SPAPPTool.mainTabBarController?.selectedReward()
|
||||
|
||||
} else if model.path == .feedback {
|
||||
let vc = SPCampaignWebViewController()
|
||||
vc.urlStr = SPFeedBackListWebUrl
|
||||
SPAPPTool.topViewController()?.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
}
|
||||
|
||||
completionHandler()
|
||||
|
@ -69,6 +69,21 @@ extension SPTabBarController {
|
||||
}
|
||||
}
|
||||
|
||||
///选择活动页面
|
||||
func selectedReward() {
|
||||
var index: Int?
|
||||
self.viewControllers?.enumerated().forEach({
|
||||
guard let nav = $1 as? UINavigationController else { return }
|
||||
if let _ = nav.viewControllers.first as? SPRewardsViewController {
|
||||
index = $0
|
||||
}
|
||||
})
|
||||
|
||||
if let index = index {
|
||||
self.selectedIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPTabBarController {
|
||||
|
@ -23,3 +23,6 @@ let kSPWaitRestoreIAPDefaultsKey = "kSPWaitRestoreIAPDefaultsKey"
|
||||
|
||||
///推送提示
|
||||
let kSPApnsAlertDefaultsKey = "kSPApnsAlertDefaultsKey"
|
||||
|
||||
///vip弹窗时间
|
||||
let kSPVipAlertDateDefaultsKey = "kSPVipAlertDateDefaultsKey"
|
||||
|
@ -416,5 +416,37 @@ extension UIColor {
|
||||
static func colorFFC555(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xFFC555, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorFFC591(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xFFC591, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorBC7616(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xBC7616, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color9C9896(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0x9C9896, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorCC9251(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xCC9251, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorCA8D3B(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xCA8D3B, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorA36C2D(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xA36C2D, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color412D11(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0x412D11, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorD0C0AA(alpha: CGFloat = 1) -> UIColor {
|
||||
return color(hex: 0xD0C0AA, alpha: alpha)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,16 @@ import SmartCodable
|
||||
|
||||
class SPOpenAppModel: SPModel, SmartCodable {
|
||||
|
||||
enum Path: String, SmartCaseDefaultable {
|
||||
case videoDetail = "detail"
|
||||
///反馈列表
|
||||
case feedback = "feedback"
|
||||
///活动
|
||||
case promotion = "promotion"
|
||||
}
|
||||
|
||||
var id: String?
|
||||
var message_id: String?
|
||||
var short_play_id: String?
|
||||
|
||||
var path: Path?
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class SPLoginViewController: SPViewController {
|
||||
let range2 = agreementStr.ocString().range(of: privacyPolicy)
|
||||
|
||||
let text = NSMutableAttributedString(string: agreementStr)
|
||||
text.font = .fontMedium(ofSize: 10)
|
||||
text.font = .fontMedium(ofSize: 12)
|
||||
text.color = .colorB0B0B3()
|
||||
|
||||
text.setTextHighlight(range1, color: .colorFFFFFF(), backgroundColor: nil) { [weak self] _, _, _, _ in
|
||||
@ -100,7 +100,7 @@ class SPLoginViewController: SPViewController {
|
||||
button.setBackgroundImage(UIImage(color: background), for: .normal)
|
||||
button.setTitle(title, for: .normal)
|
||||
button.setTitleColor(titleColor, for: .normal)
|
||||
button.jx_font = .fontMedium(ofSize: 14)
|
||||
button.jx_font = .fontMedium(ofSize: 16)
|
||||
button.space = 12
|
||||
button.setImage(icon, for: .normal)
|
||||
button.layer.cornerRadius = 8
|
||||
|
@ -67,6 +67,9 @@ class SPMineViewController: SPViewController {
|
||||
}
|
||||
|
||||
isHaveEntered = true
|
||||
|
||||
///弹出VIP提示框
|
||||
showVipAlert()
|
||||
}
|
||||
|
||||
private func updateHeaderView() {
|
||||
@ -83,6 +86,23 @@ class SPMineViewController: SPViewController {
|
||||
self?.tableView.sp_endHeaderRefreshing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SPMineViewController {
|
||||
|
||||
private func showVipAlert() {
|
||||
guard SPLoginManager.manager.userInfo?.is_vip != true else { return }
|
||||
guard SPVipAlertView.isShowAlert else { return }
|
||||
|
||||
SPWalletAPI.requestPayTemplate { model in
|
||||
guard let list = model?.list_sub_vip else { return }
|
||||
let alert = SPVipAlertView(dataArr: list).show(in: SPAPPTool.getKeyWindow())
|
||||
alert.buyFinishHandle = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.requestUserInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
|
||||
//解锁视频需要的金币
|
||||
let videoCoin = videoInfo.coins ?? 0
|
||||
|
||||
if myCoin < videoCoin {//金币不够时打开充值页面
|
||||
if myCoin < videoCoin, self.viewModel.currentPlayer?.hasLockUpEpisode == true {//金币不够时打开充值页面
|
||||
self.onPlayBuy()
|
||||
}
|
||||
return
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol SPPlayerProtocol: NSObjectProtocol {
|
||||
@objc protocol SPPlayerProtocol: NSObjectProtocol {
|
||||
|
||||
///播放完成
|
||||
var playerFinishHadle: (() -> Void)? { get set }
|
||||
@ -17,6 +17,8 @@ protocol SPPlayerProtocol: NSObjectProtocol {
|
||||
|
||||
var isCurrent: Bool { get set }
|
||||
|
||||
///上一集是否加锁
|
||||
@objc optional var hasLockUpEpisode: Bool { get set }
|
||||
|
||||
///总进度
|
||||
var duration: Int { get }
|
||||
|
@ -29,6 +29,7 @@ class SPShortModel: SPModel, SmartCodable {
|
||||
var video_info: SPVideoInfoModel?
|
||||
var watch_total: Int?
|
||||
var current_episode: String?
|
||||
var video_url: String?
|
||||
|
||||
@IgnoredKey
|
||||
var titleAttributedString: NSAttributedString?
|
||||
|
@ -12,18 +12,40 @@ class SPPlayerDetailRecommandCell: ZKCycleScrollViewCell {
|
||||
var model: SPShortModel? {
|
||||
didSet {
|
||||
coverImageView.sp_setImage(url: model?.image_url)
|
||||
|
||||
player.setPlayUrl(url: model?.video_url ?? "")
|
||||
}
|
||||
}
|
||||
|
||||
private(set) lazy var player: SPPlayer = {
|
||||
let player = SPPlayer()
|
||||
player.playerView = playerView
|
||||
player.delegate = self
|
||||
return player
|
||||
}()
|
||||
|
||||
var isCurrentPlayer: Bool = false {
|
||||
didSet {
|
||||
if !isCurrentPlayer {
|
||||
coverImageView.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var coverImageView: SPImageView = {
|
||||
let imageView = SPImageView()
|
||||
imageView.layer.cornerRadius = 6
|
||||
imageView.layer.masksToBounds = true
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var playerView: UIView = {
|
||||
let view = UIView()
|
||||
return view
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
contentView.layer.cornerRadius = 6
|
||||
contentView.layer.masksToBounds = true
|
||||
|
||||
_setupUI()
|
||||
}
|
||||
@ -36,8 +58,13 @@ class SPPlayerDetailRecommandCell: ZKCycleScrollViewCell {
|
||||
|
||||
extension SPPlayerDetailRecommandCell {
|
||||
private func _setupUI() {
|
||||
contentView.addSubview(playerView)
|
||||
contentView.addSubview(coverImageView)
|
||||
|
||||
playerView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
|
||||
coverImageView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
@ -45,3 +72,16 @@ extension SPPlayerDetailRecommandCell {
|
||||
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- SPPlayerDelegate --------------
|
||||
extension SPPlayerDetailRecommandCell: SPPlayerDelegate {
|
||||
func sp_player(_ player: SPPlayer, loadStateDidChange state: SPPlayer.LoadState) {
|
||||
|
||||
}
|
||||
|
||||
func sp_player(_ player: SPPlayer, playStateDidChanged state: SPPlayer.PlayState) {
|
||||
if state == .playing, isCurrentPlayer {
|
||||
self.coverImageView.isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,20 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
|
||||
var clickCloseButton: (() -> Void)?
|
||||
var clickPlayButton: ((_ model: SPShortModel) -> Void)?
|
||||
|
||||
|
||||
private var _currentCell: SPPlayerDetailRecommandCell?
|
||||
private var currentCell: SPPlayerDetailRecommandCell? {
|
||||
set {
|
||||
_currentCell?.player.pause()
|
||||
_currentCell?.isCurrentPlayer = false
|
||||
_currentCell = newValue
|
||||
_currentCell?.isCurrentPlayer = true
|
||||
}
|
||||
get {
|
||||
return _currentCell
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: UI属性
|
||||
private lazy var bgImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "recommand_bg_image_01"))
|
||||
@ -37,6 +51,7 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
|
||||
|
||||
private lazy var bannerView: ZKCycleScrollView = {
|
||||
let view = ZKCycleScrollView(frame: .zero, shouldInfiniteLoop: true)
|
||||
view.isAutoScroll = false
|
||||
view.delegate = self
|
||||
view.dataSource = self
|
||||
view.itemSize = CGSize(width: 231, height: 322)
|
||||
@ -80,6 +95,11 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
private func play() {
|
||||
self.currentCell?.player.start()
|
||||
}
|
||||
|
||||
//MARK: HWPanModalPresentable
|
||||
override func longFormHeight() -> PanModalHeight {
|
||||
return PanModalHeightMake(.content, 540 + kSPTabbarSafeBottomMargin)
|
||||
@ -106,6 +126,7 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
|
||||
override func allowsPullDownWhenShortState() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPPlayerDetailRecommandView {
|
||||
@ -191,8 +212,11 @@ extension SPPlayerDetailRecommandView: ZKCycleScrollViewDelegate, ZKCycleScrollV
|
||||
let model = self.dataArr[toIndex]
|
||||
videoNameLabel.text = model.name
|
||||
|
||||
let cell = self.bannerView.cellForItem(at: toIndex) as? SPPlayerDetailRecommandCell
|
||||
self.currentCell = cell
|
||||
self.play()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension SPPlayerDetailRecommandView {
|
||||
@ -205,7 +229,14 @@ extension SPPlayerDetailRecommandView {
|
||||
let model = self.dataArr.first
|
||||
self.videoNameLabel.text = model?.name
|
||||
|
||||
CATransaction.setCompletionBlock {
|
||||
let cell = self.bannerView.cellForItem(at: 0) as? SPPlayerDetailRecommandCell
|
||||
self.currentCell = cell
|
||||
self.play()
|
||||
}
|
||||
CATransaction.begin()
|
||||
self.bannerView.reloadData()
|
||||
CATransaction.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
119
MoviaBox/Class/Wallet/View/SPVipAlertCell.swift
Normal file
119
MoviaBox/Class/Wallet/View/SPVipAlertCell.swift
Normal file
@ -0,0 +1,119 @@
|
||||
//
|
||||
// SPVipAlertCell.swift
|
||||
// MoviaBox
|
||||
//
|
||||
// Created by 佳尔 on 2025/5/14.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPVipAlertCell: SPCollectionViewCell {
|
||||
|
||||
var model: SPPayTemplateItem? {
|
||||
didSet {
|
||||
moneyLabel.text = "\(model?.currency ?? "")\(model?.price ?? "")"
|
||||
|
||||
titleLabel.text = model?.vip_type_key?.getText().capitalizingFirstLetter()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var bgView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = .colorFFFFFF()
|
||||
view.layer.cornerRadius = 8
|
||||
view.layer.masksToBounds = true
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontBold(ofSize: 18)
|
||||
label.textColor = .colorCA8D3B()
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var desLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 12)
|
||||
label.textColor = .colorD0C0AA()
|
||||
label.text = "movia_vip_membership".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var moneyBgView: SPGradientView = {
|
||||
let view = SPGradientView()
|
||||
view.colors = [UIColor.colorA36C2D().cgColor, UIColor.color412D11().cgColor]
|
||||
view.locations = [0, 1]
|
||||
view.startPoint = .init(x: 0, y: 0.5)
|
||||
view.endPoint = .init(x: 1, y: 0.5)
|
||||
view.layer.cornerRadius = 18
|
||||
view.layer.masksToBounds = true
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var moneyLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontBold(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
contentView.layer.cornerRadius = 8
|
||||
contentView.layer.masksToBounds = true
|
||||
contentView.backgroundColor = .colorCC9251()
|
||||
|
||||
|
||||
_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPVipAlertCell {
|
||||
|
||||
private func _setupUI() {
|
||||
contentView.addSubview(bgView)
|
||||
bgView.addSubview(titleLabel)
|
||||
bgView.addSubview(desLabel)
|
||||
bgView.addSubview(moneyBgView)
|
||||
moneyBgView.addSubview(moneyLabel)
|
||||
|
||||
bgView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(1)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(1)
|
||||
make.bottom.equalToSuperview().offset(-5)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(25)
|
||||
make.top.equalToSuperview().offset(11)
|
||||
}
|
||||
|
||||
desLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(titleLabel)
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(2)
|
||||
}
|
||||
|
||||
moneyBgView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.right.equalToSuperview().offset(-25)
|
||||
make.height.equalTo(36)
|
||||
}
|
||||
|
||||
moneyLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.centerX.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(13)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
200
MoviaBox/Class/Wallet/View/SPVipAlertView.swift
Normal file
200
MoviaBox/Class/Wallet/View/SPVipAlertView.swift
Normal file
@ -0,0 +1,200 @@
|
||||
//
|
||||
// SPVipAlertView.swift
|
||||
// MoviaBox
|
||||
//
|
||||
// Created by 佳尔 on 2025/5/14.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SPVipAlertView: SPAlertView {
|
||||
|
||||
///上一次弹窗时间
|
||||
static var lastAlertDate: Date? = UserDefaults.standard.object(forKey: kSPVipAlertDateDefaultsKey) as? Date {
|
||||
didSet {
|
||||
UserDefaults.standard.set(lastAlertDate, forKey: kSPVipAlertDateDefaultsKey)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
}
|
||||
|
||||
static var isShowAlert: Bool {
|
||||
guard let lastAlertDate = lastAlertDate else { return true }
|
||||
let nowDate = Date()
|
||||
|
||||
let interval = nowDate.timeIntervalSince1970 - lastAlertDate.timeIntervalSince1970
|
||||
|
||||
//一个小时弹出一次
|
||||
if interval > 60 * 60 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var dataArr: [SPPayTemplateItem] = []
|
||||
///会员购买成功
|
||||
var buyFinishHandle: (() -> Void)?
|
||||
|
||||
//MARK: UI属性
|
||||
private lazy var bgImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "alert_bg_image_02"))
|
||||
imageView.isUserInteractionEnabled = true
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var vipIconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "vip_icon_09"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var vipTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 16)
|
||||
label.textColor = .colorFFC591()
|
||||
label.text = "movia_vip_alert_text_01".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var vipTipLabel1: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorBC7616()
|
||||
label.text = "movia_vip_alert_text_02".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var vipTipLabel2: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .color9C9896()
|
||||
label.text = "movia_buy_menber_tip".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||
let layout = UICollectionViewFlowLayout()
|
||||
layout.scrollDirection = .vertical
|
||||
layout.itemSize = CGSize(width: 293, height: 65)
|
||||
layout.minimumLineSpacing = 7
|
||||
return layout
|
||||
}()
|
||||
|
||||
private lazy var collectionView: SPCollectionView = {
|
||||
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||
collectionView.delegate = self
|
||||
collectionView.dataSource = self
|
||||
collectionView.isScrollEnabled = false
|
||||
SPVipAlertCell.registerCell(collectionView: collectionView)
|
||||
return collectionView
|
||||
}()
|
||||
|
||||
private lazy var closeButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "close_icon_02"), for: .normal)
|
||||
button.addTarget(self, action: #selector(handleCloseButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
init(dataArr: [SPPayTemplateItem]) {
|
||||
super.init(frame: .zero)
|
||||
self.dataArr = dataArr
|
||||
|
||||
_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func show(in view: UIView? = nil) -> Self {
|
||||
//记录弹出时间
|
||||
SPVipAlertView.lastAlertDate = Date()
|
||||
return super.show(in: view)
|
||||
}
|
||||
|
||||
@objc private func handleCloseButton() {
|
||||
self.dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SPVipAlertView {
|
||||
|
||||
private func _setupUI() {
|
||||
contentView.frame = CGRect(x: 0, y: 0, width: bgImageView.image?.size.width ?? 0, height: (bgImageView.image?.size.height ?? 0) + 66)
|
||||
|
||||
self.addSubview(contentView)
|
||||
contentView.addSubview(bgImageView)
|
||||
contentView.addSubview(closeButton)
|
||||
bgImageView.addSubview(vipIconImageView)
|
||||
bgImageView.addSubview(vipTitleLabel)
|
||||
bgImageView.addSubview(vipTipLabel1)
|
||||
bgImageView.addSubview(vipTipLabel2)
|
||||
bgImageView.addSubview(collectionView)
|
||||
|
||||
bgImageView.snp.makeConstraints { make in
|
||||
make.left.right.top.equalToSuperview()
|
||||
make.bottom.equalToSuperview().offset(-66)
|
||||
}
|
||||
|
||||
closeButton.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
vipIconImageView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(42)
|
||||
make.top.equalToSuperview().offset(57)
|
||||
}
|
||||
|
||||
vipTitleLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(vipIconImageView)
|
||||
make.top.equalTo(vipIconImageView.snp.bottom).offset(11)
|
||||
}
|
||||
|
||||
vipTipLabel1.snp.makeConstraints { make in
|
||||
make.left.equalTo(vipTitleLabel)
|
||||
make.top.equalToSuperview().offset(138)
|
||||
}
|
||||
|
||||
vipTipLabel2.snp.makeConstraints { make in
|
||||
make.bottom.equalToSuperview().offset(-19)
|
||||
make.centerX.equalToSuperview()
|
||||
}
|
||||
|
||||
collectionView.snp.makeConstraints { make in
|
||||
make.width.equalTo(collectionViewLayout.itemSize.width)
|
||||
make.height.equalTo(collectionViewLayout.itemSize.height * 4 + collectionViewLayout.minimumLineSpacing * 3)
|
||||
make.centerX.equalToSuperview()
|
||||
make.bottom.equalToSuperview().offset(-50)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource --------------
|
||||
extension SPVipAlertView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
let cell = SPVipAlertCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
||||
cell.model = dataArr[indexPath.row]
|
||||
return cell
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return self.dataArr.count
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
let model = dataArr[indexPath.row]
|
||||
|
||||
SPIAPManager.manager.startRecharge(model: model, shortPlayId: nil, videoId: nil) { [weak self] finish in
|
||||
if finish {
|
||||
self?.buyFinishHandle?()
|
||||
self?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -17,13 +17,9 @@ class SPAlertView: UIView {
|
||||
private var alertHeight: CGFloat = 284
|
||||
|
||||
//MARK: UI属性
|
||||
private lazy var contentView: UIView = {
|
||||
private(set) lazy var contentView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = .color202531()
|
||||
view.layer.cornerRadius = 18
|
||||
view.layer.masksToBounds = true
|
||||
view.layer.borderWidth = 1
|
||||
view.layer.borderColor = UIColor.color3D4556().cgColor
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
@ -64,6 +60,10 @@ class SPAlertView: UIView {
|
||||
return button
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
self.backgroundColor = .color000000(alpha: 0.8)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
@ -72,6 +72,8 @@ class SPAlertView: UIView {
|
||||
init(iconImage: UIImage?, text: String, cancelTitle: String, sureTitle: String) {
|
||||
super.init(frame: UIScreen.main.bounds)
|
||||
self.backgroundColor = .color000000(alpha: 0.8)
|
||||
setContentNormalStyle()
|
||||
|
||||
alertHeight = 0
|
||||
|
||||
// contentView.frame = CGRect(x: 0, y: 0, width: alertWidth, height: alertHeight)
|
||||
@ -108,20 +110,35 @@ class SPAlertView: UIView {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private func setContentNormalStyle() {
|
||||
self.contentView.backgroundColor = .color202531()
|
||||
self.contentView.layer.cornerRadius = 18
|
||||
self.contentView.layer.masksToBounds = true
|
||||
self.contentView.layer.borderWidth = 1
|
||||
self.contentView.layer.borderColor = UIColor.color3D4556().cgColor
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension SPAlertView {
|
||||
// MARK: - 弹出
|
||||
@discardableResult func show() -> Self {
|
||||
SPAlertWindowManager.manager.createWindow().addSubview(self)
|
||||
@discardableResult
|
||||
@objc func show(in view: UIView? = nil) -> Self {
|
||||
var inView: UIView
|
||||
if let view = view {
|
||||
inView = view
|
||||
} else {
|
||||
inView = SPAlertWindowManager.manager.createWindow()
|
||||
}
|
||||
|
||||
inView.addSubview(self)
|
||||
self.frame = inView.bounds
|
||||
creatShowAnimation()
|
||||
|
||||
return self
|
||||
}
|
||||
func dismiss() {
|
||||
@objc func dismiss() {
|
||||
removeFromSuperview()
|
||||
SPAlertWindowManager.manager.dismissWindow()
|
||||
}
|
||||
|
@ -29,10 +29,16 @@ class SPAlertWindowManager {
|
||||
}
|
||||
|
||||
func dismissWindow() {
|
||||
count -= 1
|
||||
if count == 0 {
|
||||
window?.isHidden = true
|
||||
window = nil
|
||||
// count -= 1
|
||||
guard let window = self.window else { return }
|
||||
if window.subviews.count <= 0 {
|
||||
window.isHidden = true
|
||||
self.window = nil
|
||||
}
|
||||
|
||||
// if count == 0 {
|
||||
// window?.isHidden = true
|
||||
// window = nil
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
22
MoviaBox/Source/Assets.xcassets/icon/close_icon_02.imageset/Contents.json
vendored
Normal file
22
MoviaBox/Source/Assets.xcassets/icon/close_icon_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "关闭按钮@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "关闭按钮@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
MoviaBox/Source/Assets.xcassets/icon/close_icon_02.imageset/关闭按钮@2x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/icon/close_icon_02.imageset/关闭按钮@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
MoviaBox/Source/Assets.xcassets/icon/close_icon_02.imageset/关闭按钮@3x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/icon/close_icon_02.imageset/关闭按钮@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
22
MoviaBox/Source/Assets.xcassets/icon/vip_icon_09.imageset/Contents.json
vendored
Normal file
22
MoviaBox/Source/Assets.xcassets/icon/vip_icon_09.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Union@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Union@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
MoviaBox/Source/Assets.xcassets/icon/vip_icon_09.imageset/Union@2x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/icon/vip_icon_09.imageset/Union@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
MoviaBox/Source/Assets.xcassets/icon/vip_icon_09.imageset/Union@3x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/icon/vip_icon_09.imageset/Union@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
22
MoviaBox/Source/Assets.xcassets/image/alert_bg_image_02.imageset/Contents.json
vendored
Normal file
22
MoviaBox/Source/Assets.xcassets/image/alert_bg_image_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "背景图-切图模块@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "背景图-切图模块@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
MoviaBox/Source/Assets.xcassets/image/alert_bg_image_02.imageset/背景图-切图模块@2x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/image/alert_bg_image_02.imageset/背景图-切图模块@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 170 KiB |
BIN
MoviaBox/Source/Assets.xcassets/image/alert_bg_image_02.imageset/背景图-切图模块@3x.png
vendored
Normal file
BIN
MoviaBox/Source/Assets.xcassets/image/alert_bg_image_02.imageset/背景图-切图模块@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 369 KiB |
@ -112,6 +112,11 @@
|
||||
"m_complex" = "months";
|
||||
"q_complex" = "quarter";
|
||||
"Y_complex" = "years";
|
||||
"movia_vip_membership" = "VIP Membership";
|
||||
|
||||
|
||||
"movia_vip_alert_text_01" = "Short Drama VIP Exclusive";
|
||||
"movia_vip_alert_text_02" = "Unlimited access to all series!";
|
||||
|
||||
"movia_iap_error_toast_01" = "Invalid in-app purchase";
|
||||
///没有可恢复购买
|
||||
|
Loading…
x
Reference in New Issue
Block a user