From d859febdc8edc38809f3b57553355b0598dfa3c9 Mon Sep 17 00:00:00 2001 From: zeng Date: Thu, 15 May 2025 15:31:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9UI=E6=8F=90=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8C1.0.3=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MoviaBox.xcodeproj/project.pbxproj | 4 +- .../Base/Controller/SPViewController.swift | 24 +++++ MoviaBox/Base/Extension/UIColor+SPAdd.swift | 32 +++++++ MoviaBox/Base/View/SPApnsAlertView.swift | 2 +- .../WebView/SPCampaignWebViewController.swift | 14 ++- .../Controller/SPAllShortViewController.swift | 3 +- .../Controller/SPExplorePageController.swift | 43 ++++++++- .../Home/Controller/SPAllViewController.swift | 50 +++++++++++ .../Controller/SPHomeViewController.swift | 85 +++++++++++++++--- .../Controller/SPSearchViewController.swift | 2 + .../Class/Home/View/SPHomeHeaderView.swift | 8 +- .../Class/Mine/View/SPMineWalletView.swift | 21 +++-- .../Controller/SPMyListViewController.swift | 37 +++++++- .../SPPlayerDetailViewController.swift | 2 +- .../SPPlayerListViewController.swift | 5 ++ .../View/SPPlayerDetailRecommandCell.swift | 14 ++- .../View/SPPlayerDetailRecommandView.swift | 10 ++- .../Controller/SPRewardsViewController.swift | 23 ++++- .../Controller/SPWalletViewController.swift | 2 +- .../Wallet/View/SPMemberRechargeCell.swift | 4 +- .../Class/Wallet/View/SPVipAlertCell.swift | 44 ++++++--- .../Class/Wallet/View/SPVipAlertView.swift | 45 ++++++---- .../Wallet/View/SPWalletHeaderView.swift | 2 + .../icon/all_icon_01.imageset/Contents.json | 22 +++++ .../icon/all_icon_01.imageset/Frame@2x.png | Bin 0 -> 631 bytes .../icon/all_icon_01.imageset/Frame@3x.png | Bin 0 -> 933 bytes .../reward_icon_01.imageset/Contents.json | 22 +++++ .../reward_icon_01.imageset/image 2@2x.png | Bin 0 -> 4531 bytes .../reward_icon_01.imageset/image 2@3x.png | Bin 0 -> 8522 bytes MoviaBox/Source/en.lproj/Localizable.strings | 1 + .../ZKCycleScrollViewFlowLayout.swift | 2 +- 31 files changed, 452 insertions(+), 71 deletions(-) create mode 100644 MoviaBox/Class/Home/Controller/SPAllViewController.swift create mode 100644 MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Contents.json create mode 100644 MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Frame@2x.png create mode 100644 MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Frame@3x.png create mode 100644 MoviaBox/Source/Assets.xcassets/icon/reward_icon_01.imageset/Contents.json create mode 100644 MoviaBox/Source/Assets.xcassets/icon/reward_icon_01.imageset/image 2@2x.png create mode 100644 MoviaBox/Source/Assets.xcassets/icon/reward_icon_01.imageset/image 2@3x.png diff --git a/MoviaBox.xcodeproj/project.pbxproj b/MoviaBox.xcodeproj/project.pbxproj index f1dbaa2..f4f407a 100644 --- a/MoviaBox.xcodeproj/project.pbxproj +++ b/MoviaBox.xcodeproj/project.pbxproj @@ -257,7 +257,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.2; + MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -303,7 +303,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.2; + MARKETING_VERSION = 1.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/MoviaBox/Base/Controller/SPViewController.swift b/MoviaBox/Base/Controller/SPViewController.swift index 62dfc39..6378eab 100644 --- a/MoviaBox/Base/Controller/SPViewController.swift +++ b/MoviaBox/Base/Controller/SPViewController.swift @@ -30,6 +30,12 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol { return imageView; }() + ///无网空页面 + private(set) lazy var noNetworkEmptyView: SPNoNetworkEmptyView = { + let view = SPNoNetworkEmptyView() + return view + }() + ///头部渐变色 private lazy var topGradientView: SPGradientView = { let view = SPGradientView() @@ -120,6 +126,24 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol { func handleHeaderRefresh(_ completer: (() -> Void)?) {} func handleFooterRefresh(_ completer: (() -> Void)?) {} + + ///添加无网空页面 + func addNoNetworkEmptyView(clickButton: (() -> Void)?) { + noNetworkEmptyView.clickButton = { + clickButton?() + } + view.addSubview(noNetworkEmptyView) + + noNetworkEmptyView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.centerY.equalToSuperview().offset(-50) + } + } + + ///删除无网空页面 + func removeNoNetworkEmptyView() { + noNetworkEmptyView.removeFromSuperview() + } } diff --git a/MoviaBox/Base/Extension/UIColor+SPAdd.swift b/MoviaBox/Base/Extension/UIColor+SPAdd.swift index c6a56fd..87686c8 100644 --- a/MoviaBox/Base/Extension/UIColor+SPAdd.swift +++ b/MoviaBox/Base/Extension/UIColor+SPAdd.swift @@ -448,5 +448,37 @@ extension UIColor { static func colorD0C0AA(alpha: CGFloat = 1) -> UIColor { return color(hex: 0xD0C0AA, alpha: alpha) } + + static func colorF6D8A0(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xF6D8A0, alpha: alpha) + } + + static func colorDF9F46(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xDF9F46, alpha: alpha) + } + + static func color684B2A(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0x684B2A, alpha: alpha) + } + + static func color9E692C(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0x9E692C, alpha: alpha) + } + + static func colorBE9D70(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xBE9D70, alpha: alpha) + } + + static func colorF8F1E2(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xF8F1E2, alpha: alpha) + } + + static func colorEBD5A3(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xEBD5A3, alpha: alpha) + } + + static func colorAD7433(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xAD7433, alpha: alpha) + } } diff --git a/MoviaBox/Base/View/SPApnsAlertView.swift b/MoviaBox/Base/View/SPApnsAlertView.swift index 0d91a53..8c3dabe 100644 --- a/MoviaBox/Base/View/SPApnsAlertView.swift +++ b/MoviaBox/Base/View/SPApnsAlertView.swift @@ -48,7 +48,7 @@ class SPApnsAlertView: UIView { private lazy var laterButton: UIButton = { let button = UIButton(type: .custom) - button.setTitle("Later".localized, for: .normal) + button.setTitle("movia_open_notification_later".localized, for: .normal) button.titleLabel?.font = .fontMedium(ofSize: 16) button.setTitleColor(.colorFF3232(), for: .normal) button.addTarget(self, action: #selector(handleLaterButton), for: .touchUpInside) diff --git a/MoviaBox/Base/WebView/SPCampaignWebViewController.swift b/MoviaBox/Base/WebView/SPCampaignWebViewController.swift index c37c1c3..405e613 100644 --- a/MoviaBox/Base/WebView/SPCampaignWebViewController.swift +++ b/MoviaBox/Base/WebView/SPCampaignWebViewController.swift @@ -10,6 +10,9 @@ import UIKit class SPCampaignWebViewController: SPWebViewController { var id: String? + + ///重试次数 + private var receiveDataCount = 0 override func viewDidLoad() { super.viewDidLoad() @@ -38,6 +41,7 @@ class SPCampaignWebViewController: SPWebViewController { override func webViewDidFinishLoad(_ webView: SPWebView) { super.webViewDidFinishLoad(webView) + receiveDataCount = 0 receiveDataFromNative() } @@ -46,6 +50,9 @@ class SPCampaignWebViewController: SPWebViewController { extension SPCampaignWebViewController { ///设置登录信息 func receiveDataFromNative() { + receiveDataCount += 1 + if receiveDataCount > 10 { return } + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in guard let self = self else { return } var dic = [ @@ -62,8 +69,11 @@ extension SPCampaignWebViewController { if let json = dic.toJsonString() { let js = "receiveDataFromNative(\(json))" - self.webView.evaluateJavaScript(js) { _, error in - + self.webView.evaluateJavaScript(js) { [weak self] _, error in + guard let self = self else { return } + if error != nil { + self.receiveDataFromNative() + } } } } diff --git a/MoviaBox/Class/Explore/Controller/SPAllShortViewController.swift b/MoviaBox/Class/Explore/Controller/SPAllShortViewController.swift index 8b78611..cb23c86 100644 --- a/MoviaBox/Class/Explore/Controller/SPAllShortViewController.swift +++ b/MoviaBox/Class/Explore/Controller/SPAllShortViewController.swift @@ -163,7 +163,8 @@ extension SPAllShortViewController { tagView.snp.makeConstraints { make in make.left.right.equalToSuperview() - make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12) +// make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12) + make.top.equalToSuperview().offset(kSPNavBarHeight + 12) make.height.lessThanOrEqualTo(tagMaxHeight) } diff --git a/MoviaBox/Class/Explore/Controller/SPExplorePageController.swift b/MoviaBox/Class/Explore/Controller/SPExplorePageController.swift index 85bda48..249b4ff 100644 --- a/MoviaBox/Class/Explore/Controller/SPExplorePageController.swift +++ b/MoviaBox/Class/Explore/Controller/SPExplorePageController.swift @@ -69,6 +69,7 @@ class SPExplorePageController: SPViewController { return pageView }() + private lazy var menuBgView: UIView = { let view = UIView() view.addEffectView(style: .light) @@ -77,11 +78,21 @@ class SPExplorePageController: SPViewController { return view }() + deinit { + NotificationCenter.default.removeObserver(self) + } + override func viewDidLoad() { super.viewDidLoad() - - _setupUI() + NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil) + + if SPNetworkReachabilityManager.manager.isReachable != true { + setEmptyView() + } else { + _setupUI() + } + } @@ -89,7 +100,35 @@ class SPExplorePageController: SPViewController { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(true, animated: true) } + + +} + +extension SPExplorePageController { + + ///设置无网空页面 + private func setEmptyView() { + if SPNetworkReachabilityManager.manager.isReachable != true { + self.addNoNetworkEmptyView { [weak self] in + self?.updateEmptyState() + } + } + } + + @objc private func reachabilityDidChangeNotification() { + updateEmptyState() + } + + private func updateEmptyState() { + if self.pageView.view.superview != nil { return } + + if SPNetworkReachabilityManager.manager.isReachable == true { + self._setupUI() + self.removeNoNetworkEmptyView() + } + } + } extension SPExplorePageController { diff --git a/MoviaBox/Class/Home/Controller/SPAllViewController.swift b/MoviaBox/Class/Home/Controller/SPAllViewController.swift new file mode 100644 index 0000000..0d8dd05 --- /dev/null +++ b/MoviaBox/Class/Home/Controller/SPAllViewController.swift @@ -0,0 +1,50 @@ +// +// SPAllViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/5/15. +// + +import UIKit + +class SPAllViewController: SPViewController { + + + private lazy var allVC: SPAllShortViewController = { + let vc = SPAllShortViewController() + return vc + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.edgesForExtendedLayout = .top + self.title = "movia_library".localized + + setBackgroundView(isShowGradient: false) + + _setupUI() + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + + setNavigationBackgroundColor(color: .clear, isTranslucent: true) + } + + +} + +extension SPAllViewController { + + private func _setupUI() { + addChild(allVC) + + view.addSubview(allVC.view) + + + + } + +} diff --git a/MoviaBox/Class/Home/Controller/SPHomeViewController.swift b/MoviaBox/Class/Home/Controller/SPHomeViewController.swift index 5039d71..fa33070 100644 --- a/MoviaBox/Class/Home/Controller/SPHomeViewController.swift +++ b/MoviaBox/Class/Home/Controller/SPHomeViewController.swift @@ -16,6 +16,8 @@ class SPHomeViewController: SPHomeChildController { private lazy var requestGroup = DispatchGroup() + private var isSetupUI = false + //MARK: UI属性 private lazy var logoImageView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "logo_icon_01")) @@ -30,6 +32,24 @@ class SPHomeViewController: SPHomeChildController { return button }() + private lazy var allButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "all_icon_01"), for: .normal) + button.setContentHuggingPriority(.required, for: .horizontal) + button.setContentCompressionResistancePriority(.required, for: .horizontal) + button.addTarget(self, action: #selector(handleAllButton), for: .touchUpInside) + return button + }() + + private lazy var rewardButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "reward_icon_01"), for: .normal) + button.setContentHuggingPriority(.required, for: .horizontal) + button.setContentCompressionResistancePriority(.required, for: .horizontal) + button.addTarget(self, action: #selector(handleRewardButton), for: .touchUpInside) + return button + }() + private lazy var layout: UICollectionViewFlowLayout = { let width = floor((kSPScreenWidth - 32 - 13) / 2) let height = 221 / 165 * width + 44 @@ -64,10 +84,14 @@ class SPHomeViewController: SPHomeChildController { NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil) - updateAllData(completer: nil) -// updateEmptyState() - _setupUI() + if SPNetworkReachabilityManager.manager.isReachable == true { + updateAllData(completer: nil) + _setupUI() + } else { + setEmptyView() + } + } @@ -99,11 +123,17 @@ class SPHomeViewController: SPHomeChildController { } + extension SPHomeViewController { private func _setupUI() { + if isSetupUI { return } + isSetupUI = true + // view.addSubview(logoImageView) view.addSubview(searchButton) + view.addSubview(allButton) + view.addSubview(rewardButton) view.addSubview(self.collectionView) // logoImageView.snp.makeConstraints { make in @@ -114,10 +144,22 @@ extension SPHomeViewController { searchButton.snp.makeConstraints { make in // make.left.equalTo(logoImageView.snp.right).offset(6) make.left.equalToSuperview().offset(16) - make.right.equalToSuperview().offset(-16) +// make.right.equalToSuperview().offset(-16) + make.right.equalTo(allButton.snp.left).offset(-4) make.top.equalToSuperview().offset(kSPStatusbarHeight + 10) } + allButton.snp.makeConstraints { make in + make.centerY.equalTo(searchButton) +// make.right.equalToSuperview().offset(-16) + make.right.equalTo(rewardButton.snp.left).offset(-1) + } + + rewardButton.snp.makeConstraints { make in + make.centerY.equalTo(searchButton) + make.right.equalToSuperview().offset(-16) + } + self.collectionView.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() // make.top.equalToSuperview().offset(kSPStatusbarHeight + 66) @@ -132,21 +174,38 @@ extension SPHomeViewController { self.navigationController?.pushViewController(vc, animated: true) } - @objc private func reachabilityDidChangeNotification() { - if SPNetworkReachabilityManager.manager.isReachable == true, self.viewModel.moduleModel == nil { - updateAllData(completer: nil) + ///设置无网空页面 + private func setEmptyView() { + if SPNetworkReachabilityManager.manager.isReachable != true { + self.addNoNetworkEmptyView { [weak self] in + self?.updateEmptyState() + } } } + + @objc private func reachabilityDidChangeNotification() { + updateEmptyState() + } + ///更新空白页面状态 private func updateEmptyState() { - - if SPNetworkReachabilityManager.manager.isReachable != true, viewModel.isEmptyData { - self.collectionView.showNoNetworkEmpty { [weak self] in - self?.updateAllData(completer: nil) + if SPNetworkReachabilityManager.manager.isReachable == true { + self._setupUI() + if viewModel.isEmptyData { + self.updateAllData(completer: nil) } - } else { - self.collectionView.hiddenEmpty() + self.removeNoNetworkEmptyView() } + } + + @objc private func handleAllButton() { + let vc = SPAllViewController() + self.navigationController?.pushViewController(vc, animated: true) + } + + @objc private func handleRewardButton() { + let vc = SPRewardsViewController() + self.navigationController?.pushViewController(vc, animated: true) } } diff --git a/MoviaBox/Class/Home/Controller/SPSearchViewController.swift b/MoviaBox/Class/Home/Controller/SPSearchViewController.swift index f5a5038..a09a9c1 100644 --- a/MoviaBox/Class/Home/Controller/SPSearchViewController.swift +++ b/MoviaBox/Class/Home/Controller/SPSearchViewController.swift @@ -60,6 +60,8 @@ class SPSearchViewController: SPViewController { searchInputView.textField.becomeFirstResponder() + setBackgroundView(isShowGradient: false, bgImage: nil) + _setupUI() } diff --git a/MoviaBox/Class/Home/View/SPHomeHeaderView.swift b/MoviaBox/Class/Home/View/SPHomeHeaderView.swift index 6083bda..c140c61 100644 --- a/MoviaBox/Class/Home/View/SPHomeHeaderView.swift +++ b/MoviaBox/Class/Home/View/SPHomeHeaderView.swift @@ -44,7 +44,9 @@ class SPHomeHeaderView: UICollectionReusableView { // stackView.addArrangedSubview(shortsForYouView) // shortsForYouView.dataArr = moduleModel?.bannerData - stackView.addArrangedSubview(titleView) + if (viewModel?.dataArr.count ?? 0) > 0 { + stackView.addArrangedSubview(titleView) + } } } @@ -66,9 +68,9 @@ class SPHomeHeaderView: UICollectionReusableView { let view = ZKCycleScrollView(frame: .zero, shouldInfiniteLoop: true) view.itemSize = .init(width: 234, height: Self.bannerHeight()) view.itemAlpha = true - view.itemZoomScale = 0.9 - view.itemSpacing = 30 + view.itemZoomScale = 0.85 view.rotationAngle = 12 + view.itemSpacing = 15 view.delegate = self view.dataSource = self view.hidesPageControl = true diff --git a/MoviaBox/Class/Mine/View/SPMineWalletView.swift b/MoviaBox/Class/Mine/View/SPMineWalletView.swift index 5135e4f..5e5084f 100644 --- a/MoviaBox/Class/Mine/View/SPMineWalletView.swift +++ b/MoviaBox/Class/Mine/View/SPMineWalletView.swift @@ -10,11 +10,11 @@ import UIKit class SPMineWalletView: UIView { override var intrinsicContentSize: CGSize { - if isShowMore { - return .init(width: kSPScreenWidth, height: 119) - } else { - return .init(width: kSPScreenWidth, height: 82) - } + return .init(width: kSPScreenWidth, height: 119) +// if isShowMore { +// } else { +// return .init(width: kSPScreenWidth, height: 82) +// } } var userInfo: SPUserInfo? { @@ -27,21 +27,19 @@ class SPMineWalletView: UIView { ///是否展示更多按钮 var isShowMore: Bool = true { didSet { - moreButton.isHidden = !isShowMore - lineView.isHidden = !isShowMore + moreIndicatorImageView.isHidden = !isShowMore +// lineView.isHidden = !isShowMore - invalidateIntrinsicContentSize() +// invalidateIntrinsicContentSize() } } //MARK: UI属性 - private lazy var bgView: UIView = { + private(set) lazy var bgView: UIView = { let view = UIView() view.backgroundColor = .colorFFFFFF(alpha: 0.06) view.layer.cornerRadius = 8 view.layer.masksToBounds = true - view.layer.borderWidth = 1 - view.layer.borderColor = UIColor.colorFFFFFF(alpha: 0.14).cgColor return view }() @@ -122,6 +120,7 @@ extension SPMineWalletView { } @objc private func handleWalletButton() { + if !isShowMore { return } let vc = SPWalletViewController() self.viewController?.navigationController?.pushViewController(vc, animated: true) } diff --git a/MoviaBox/Class/MyList/Controller/SPMyListViewController.swift b/MoviaBox/Class/MyList/Controller/SPMyListViewController.swift index 954267c..088d6f8 100644 --- a/MoviaBox/Class/MyList/Controller/SPMyListViewController.swift +++ b/MoviaBox/Class/MyList/Controller/SPMyListViewController.swift @@ -112,10 +112,19 @@ class SPMyListViewController: SPViewController { return view }() + deinit { + NotificationCenter.default.removeObserver(self) + } + override func viewDidLoad() { super.viewDidLoad() + NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil) - _setupUI() + if SPNetworkReachabilityManager.manager.isReachable != true { + setEmptyView() + } else { + _setupUI() + } } @@ -149,6 +158,32 @@ class SPMyListViewController: SPViewController { } } +extension SPMyListViewController { + + ///设置无网空页面 + private func setEmptyView() { + if SPNetworkReachabilityManager.manager.isReachable != true { + self.addNoNetworkEmptyView { [weak self] in + self?.updateEmptyState() + } + } + } + + @objc private func reachabilityDidChangeNotification() { + updateEmptyState() + } + + private func updateEmptyState() { + if self.pageView.view.superview != nil { return } + + if SPNetworkReachabilityManager.manager.isReachable == true { + self._setupUI() + self.removeNoNetworkEmptyView() + } + } + +} + extension SPMyListViewController { private func _setupUI() { addChild(pageView) diff --git a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift index 7274044..52874a6 100644 --- a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift +++ b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift @@ -107,7 +107,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController { //解锁视频需要的金币 let videoCoin = videoInfo.coins ?? 0 - if myCoin < videoCoin, self.viewModel.currentPlayer?.hasLockUpEpisode == true {//金币不够时打开充值页面 + if myCoin < videoCoin, self.viewModel.currentPlayer?.hasLockUpEpisode != true {//金币不够时打开充值页面 self.onPlayBuy() } return diff --git a/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift b/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift index c7d77a7..fb23382 100644 --- a/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift +++ b/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift @@ -121,6 +121,11 @@ class SPPlayerListViewController: SPViewController { override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.viewModel.currentPlayer?.pause() + ///处理切换页面后,滑动代理scrollViewDidEndDecelerating不执行的问题 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in + guard let self = self else { return } + self.scrollDidEnd(self.collectionView) + } } diff --git a/MoviaBox/Class/Player/View/SPPlayerDetailRecommandCell.swift b/MoviaBox/Class/Player/View/SPPlayerDetailRecommandCell.swift index e26007b..e5b2f80 100644 --- a/MoviaBox/Class/Player/View/SPPlayerDetailRecommandCell.swift +++ b/MoviaBox/Class/Player/View/SPPlayerDetailRecommandCell.swift @@ -76,11 +76,21 @@ extension SPPlayerDetailRecommandCell { //MARK: -------------- SPPlayerDelegate -------------- extension SPPlayerDetailRecommandCell: SPPlayerDelegate { func sp_player(_ player: SPPlayer, loadStateDidChange state: SPPlayer.LoadState) { - + updateCoverShowState() } func sp_player(_ player: SPPlayer, playStateDidChanged state: SPPlayer.PlayState) { - if state == .playing, isCurrentPlayer { +// if state == .playing, isCurrentPlayer { +// self.coverImageView.isHidden = true +// } + updateCoverShowState() + } + + ///更新封面显示状态 + private func updateCoverShowState() { + let loadState = self.player.loadState + let playState = self.player.playState + if isCurrentPlayer && (loadState == .playable || loadState == .playthroughOK) && (playState == .playing) { self.coverImageView.isHidden = true } } diff --git a/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift b/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift index 854fa08..cb55b35 100644 --- a/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift @@ -211,10 +211,14 @@ extension SPPlayerDetailRecommandView: ZKCycleScrollViewDelegate, ZKCycleScrollV func cycleScrollView(_ cycleScrollView: ZKCycleScrollView, didScrollFromIndex fromIndex: Int, toIndex: Int) { let model = self.dataArr[toIndex] videoNameLabel.text = model.name + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in + guard let self = self else { return } + + let cell = self.bannerView.cellForItem(at: toIndex) as? SPPlayerDetailRecommandCell + self.currentCell = cell + self.play() + } - let cell = self.bannerView.cellForItem(at: toIndex) as? SPPlayerDetailRecommandCell - self.currentCell = cell - self.play() } } diff --git a/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift b/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift index e08278a..a90b328 100644 --- a/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift +++ b/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift @@ -20,9 +20,11 @@ class SPRewardsViewController: SPCampaignWebViewController { self.urlStr = SPRewardsWebUrl super.viewDidLoad() - + NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(loginStateDidChangeNotification), name: SPLoginManager.loginStateDidChangeNotification, object: nil) + setEmptyView() + } @@ -40,7 +42,26 @@ class SPRewardsViewController: SPCampaignWebViewController { extension SPRewardsViewController { + + ///设置无网空页面 + private func setEmptyView() { + if SPNetworkReachabilityManager.manager.isReachable != true { + self.webView.isHidden = true + self.addNoNetworkEmptyView { [weak self] in + self?.reachabilityDidChangeNotification() + } + } + } + @objc private func loginStateDidChangeNotification() { self.reload() } + + @objc private func reachabilityDidChangeNotification() { + if SPNetworkReachabilityManager.manager.isReachable == true { + self.webView.isHidden = false + self.removeNoNetworkEmptyView() + self.reload() + } + } } diff --git a/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift b/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift index 567498e..db8769e 100644 --- a/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift +++ b/MoviaBox/Class/Wallet/Controller/SPWalletViewController.swift @@ -31,7 +31,7 @@ class SPWalletViewController: SPViewController { }() private lazy var headerView: SPWalletHeaderView = { - let view = SPWalletHeaderView(frame: .init(x: 0, y: 0, width: kSPScreenWidth, height: 115)) + let view = SPWalletHeaderView(frame: .init(x: 0, y: 0, width: kSPScreenWidth, height: 152)) view.userInfo = SPLoginManager.manager.userInfo return view }() diff --git a/MoviaBox/Class/Wallet/View/SPMemberRechargeCell.swift b/MoviaBox/Class/Wallet/View/SPMemberRechargeCell.swift index a8f526e..a03b918 100644 --- a/MoviaBox/Class/Wallet/View/SPMemberRechargeCell.swift +++ b/MoviaBox/Class/Wallet/View/SPMemberRechargeCell.swift @@ -13,7 +13,8 @@ class SPMemberRechargeCell: SPCollectionViewCell { var model: SPPayTemplateItem? { didSet { desLabel.text = model?.sp_description - typeLabel.text = model?.vip_type_key?.getText() +// typeLabel.text = model?.vip_type_key?.getText() + typeLabel.text = model?.brief currencyLabel.text = model?.currency moneyLabel.text = model?.price if let sendCoins = model?.send_coins, sendCoins > 0 { @@ -120,6 +121,7 @@ class SPMemberRechargeCell: SPCollectionViewCell { private lazy var typeIconImageView: UIImageView = { let imageView = UIImageView() + imageView.isHidden = true return imageView }() diff --git a/MoviaBox/Class/Wallet/View/SPVipAlertCell.swift b/MoviaBox/Class/Wallet/View/SPVipAlertCell.swift index d5f136b..00d25b0 100644 --- a/MoviaBox/Class/Wallet/View/SPVipAlertCell.swift +++ b/MoviaBox/Class/Wallet/View/SPVipAlertCell.swift @@ -13,14 +13,37 @@ class SPVipAlertCell: SPCollectionViewCell { didSet { moneyLabel.text = "\(model?.currency ?? "")\(model?.price ?? "")" - titleLabel.text = model?.vip_type_key?.getText().capitalizingFirstLetter() +// titleLabel.text = model?.vip_type_key?.getText().capitalizingFirstLetter() + titleLabel.text = model?.brief } } - private lazy var bgView: UIView = { - let view = UIView() - view.backgroundColor = .colorFFFFFF() + var sp_isSelected: Bool = false { + didSet { + if sp_isSelected { + bgView.colors = [UIColor.colorF6D8A0().cgColor, UIColor.colorDF9F46().cgColor] + contentView.backgroundColor = .color684B2A() + titleLabel.textColor = .color9E692C() + desLabel.textColor = .colorBE9D70() + moneyBgView.colors = [UIColor.colorF8F1E2().cgColor, UIColor.colorEBD5A3().cgColor] + moneyLabel.textColor = .colorAD7433() + } else { + bgView.colors = [UIColor.colorFFFFFF().cgColor, UIColor.colorFFFFFF().cgColor] + contentView.backgroundColor = .colorCC9251() + titleLabel.textColor = .colorCA8D3B() + desLabel.textColor = .colorD0C0AA() + moneyBgView.colors = [UIColor.colorA36C2D().cgColor, UIColor.color412D11().cgColor] + moneyLabel.textColor = .colorFFFFFF() + } + } + } + + private lazy var bgView: SPGradientView = { + let view = SPGradientView() + view.locations = [0, 1] + view.startPoint = .init(x: 0, y: 0.5) + view.endPoint = .init(x: 1, y: 0.5) view.layer.cornerRadius = 8 view.layer.masksToBounds = true return view @@ -29,21 +52,19 @@ class SPVipAlertCell: SPCollectionViewCell { private lazy var titleLabel: UILabel = { let label = UILabel() label.font = .fontBold(ofSize: 18) - label.textColor = .colorCA8D3B() + label.adjustsFontSizeToFitWidth = true 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) @@ -56,6 +77,8 @@ class SPVipAlertCell: SPCollectionViewCell { let label = UILabel() label.font = .fontBold(ofSize: 14) label.textColor = .colorFFFFFF() + label.setContentHuggingPriority(.required, for: .horizontal) + label.setContentCompressionResistancePriority(.required, for: .horizontal) return label }() @@ -65,7 +88,7 @@ class SPVipAlertCell: SPCollectionViewCell { contentView.layer.cornerRadius = 8 contentView.layer.masksToBounds = true - contentView.backgroundColor = .colorCC9251() + _setupUI() @@ -94,8 +117,9 @@ extension SPVipAlertCell { } titleLabel.snp.makeConstraints { make in - make.left.equalToSuperview().offset(25) + make.left.equalToSuperview().offset(15) make.top.equalToSuperview().offset(11) + make.right.lessThanOrEqualTo(moneyBgView.snp.left).offset(-5) } desLabel.snp.makeConstraints { make in @@ -105,7 +129,7 @@ extension SPVipAlertCell { moneyBgView.snp.makeConstraints { make in make.centerY.equalToSuperview() - make.right.equalToSuperview().offset(-25) + make.right.equalToSuperview().offset(-15) make.height.equalTo(36) } diff --git a/MoviaBox/Class/Wallet/View/SPVipAlertView.swift b/MoviaBox/Class/Wallet/View/SPVipAlertView.swift index 628417c..2ee961b 100644 --- a/MoviaBox/Class/Wallet/View/SPVipAlertView.swift +++ b/MoviaBox/Class/Wallet/View/SPVipAlertView.swift @@ -18,6 +18,9 @@ class SPVipAlertView: SPAlertView { } static var isShowAlert: Bool { +#if DEBUG + return true +#else guard let lastAlertDate = lastAlertDate else { return true } let nowDate = Date() @@ -29,12 +32,16 @@ class SPVipAlertView: SPAlertView { } else { return false } +#endif + } private lazy var dataArr: [SPPayTemplateItem] = [] ///会员购买成功 var buyFinishHandle: (() -> Void)? + private var selectedIndex = 0 + //MARK: UI属性 private lazy var bgImageView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "alert_bg_image_02")) @@ -47,13 +54,15 @@ class SPVipAlertView: SPAlertView { 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 vipTitleLabel: UILabel = { +// let label = UILabel() +// label.font = .fontMedium(ofSize: 16) +// label.textColor = .colorFFC591() +// label.text = "movia_vip_alert_text_01".localized +// label.numberOfLines = 2 +//// label.adjustsFontSizeToFitWidth = true +// return label +// }() private lazy var vipTipLabel1: UILabel = { let label = UILabel() @@ -83,7 +92,7 @@ class SPVipAlertView: SPAlertView { let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) collectionView.delegate = self collectionView.dataSource = self - collectionView.isScrollEnabled = false + collectionView.showsVerticalScrollIndicator = false SPVipAlertCell.registerCell(collectionView: collectionView) return collectionView }() @@ -97,6 +106,7 @@ class SPVipAlertView: SPAlertView { init(dataArr: [SPPayTemplateItem]) { super.init(frame: .zero) + selectedIndex = dataArr.count - 1 self.dataArr = dataArr _setupUI() @@ -127,7 +137,7 @@ extension SPVipAlertView { contentView.addSubview(bgImageView) contentView.addSubview(closeButton) bgImageView.addSubview(vipIconImageView) - bgImageView.addSubview(vipTitleLabel) +// bgImageView.addSubview(vipTitleLabel) bgImageView.addSubview(vipTipLabel1) bgImageView.addSubview(vipTipLabel2) bgImageView.addSubview(collectionView) @@ -144,16 +154,18 @@ extension SPVipAlertView { vipIconImageView.snp.makeConstraints { make in make.left.equalToSuperview().offset(42) - make.top.equalToSuperview().offset(57) +// make.top.equalToSuperview().offset(57) + make.top.equalToSuperview().offset(70) } - vipTitleLabel.snp.makeConstraints { make in - make.left.equalTo(vipIconImageView) - make.top.equalTo(vipIconImageView.snp.bottom).offset(11) - } +// vipTitleLabel.snp.makeConstraints { make in +// make.left.equalTo(vipIconImageView) +// make.top.equalTo(vipIconImageView.snp.bottom).offset(11) +// make.right.lessThanOrEqualToSuperview().offset(-140) +// } vipTipLabel1.snp.makeConstraints { make in - make.left.equalTo(vipTitleLabel) + make.left.equalTo(vipIconImageView) make.top.equalToSuperview().offset(138) } @@ -178,6 +190,7 @@ 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] + cell.sp_isSelected = indexPath.row == selectedIndex return cell } @@ -186,6 +199,8 @@ extension SPVipAlertView: UICollectionViewDelegate, UICollectionViewDataSource { } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + selectedIndex = indexPath.row + collectionView.reloadData() let model = dataArr[indexPath.row] SPIAPManager.manager.startRecharge(model: model, shortPlayId: nil, videoId: nil) { [weak self] finish in diff --git a/MoviaBox/Class/Wallet/View/SPWalletHeaderView.swift b/MoviaBox/Class/Wallet/View/SPWalletHeaderView.swift index a97ec0d..01d098b 100644 --- a/MoviaBox/Class/Wallet/View/SPWalletHeaderView.swift +++ b/MoviaBox/Class/Wallet/View/SPWalletHeaderView.swift @@ -19,6 +19,8 @@ class SPWalletHeaderView: UIView { private lazy var contentView: SPMineWalletView = { let view = SPMineWalletView() view.isShowMore = false + view.bgView.layer.borderWidth = 1 + view.bgView.layer.borderColor = UIColor.colorFFFFFF(alpha: 0.14).cgColor return view }() diff --git a/MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Frame@2x.png b/MoviaBox/Source/Assets.xcassets/icon/all_icon_01.imageset/Frame@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ee6a67fe35471e8fb2e483b62bc1a568cfeb7a91 GIT binary patch literal 631 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 RIh_Ci002ovPDHLkV1f$wlt};p literal 0 HcmV?d00001 diff --git a/MoviaBox/Source/Assets.xcassets/icon/reward_icon_01.imageset/image 2@3x.png b/MoviaBox/Source/Assets.xcassets/icon/reward_icon_01.imageset/image 2@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..26fc1c71cf23878f8a91355b1fe744d8ec2fc273 GIT binary patch literal 8522 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 1 {