Commit 10caad0a authored by shenyong's avatar shenyong

处理退款,修复保留bug,首页视频播放

parent b2f471d2
...@@ -188,6 +188,7 @@ extension IAPManager { ...@@ -188,6 +188,7 @@ extension IAPManager {
verifyReceiptWithApple { result in verifyReceiptWithApple { result in
switch result { switch result {
case .success(let receipt): case .success(let receipt):
// print("收据信息:\(receipt)")
let status = self.checkSubscriptionStatus(receiptInfo: receipt) let status = self.checkSubscriptionStatus(receiptInfo: receipt)
DispatchQueue.main.async { DispatchQueue.main.async {
completion(status.isActive, status.subscriptionType, status.expiresDate) completion(status.isActive, status.subscriptionType, status.expiresDate)
...@@ -570,12 +571,18 @@ extension IAPManager{ ...@@ -570,12 +571,18 @@ extension IAPManager{
if let receipt = receiptInfo["receipt"] as? [String: Any], if let receipt = receiptInfo["receipt"] as? [String: Any],
let inAppPurchases = receipt["in_app"] as? [[String: Any]] { let inAppPurchases = receipt["in_app"] as? [[String: Any]] {
// 检查是否存在永久商品购买记录 // 检查是否存在永久商品购买记录
let hasLifetimePurchase = inAppPurchases.contains { purchase in let hasValidLifetimePurchase = inAppPurchases.contains { purchase in
return purchase["product_id"] as? String == ProductID.lifetimeMember let productId = purchase["product_id"] as? String
let cancelled = purchase["cancellation_date"] != nil
let ownershipType = purchase["in_app_ownership_type"] as? String
return productId == ProductID.lifetimeMember &&
!cancelled &&
ownershipType == "PURCHASED"
} }
if hasLifetimePurchase { if hasValidLifetimePurchase {
print("检测到永久商品购买记录") print("检测到有效的永久商品购买记录")
return (true, false, .lifetime, nil) return (true, false, .lifetime, nil)
} }
} }
...@@ -600,9 +607,10 @@ extension IAPManager{ ...@@ -600,9 +607,10 @@ extension IAPManager{
// 解析试用期状态 // 解析试用期状态
let isTrial = (lastReceipt["is_trial_period"] as? String) == "true" let isTrial = (lastReceipt["is_trial_period"] as? String) == "true"
// 获取过期时间 // 获取过期时间和退款状态
let expiresDate = getExpiryDate(from: lastReceipt) let expiresDate = getExpiryDate(from: lastReceipt)
let isActive = expiresDate?.compare(Date()) == .orderedDescending let isCancelled = lastReceipt["cancellation_date"] != nil
let isActive = !isCancelled && (expiresDate?.compare(Date()) == .orderedDescending)
// 确定订阅类型 // 确定订阅类型
let productId = lastReceipt["product_id"] as? String let productId = lastReceipt["product_id"] as? String
......
...@@ -79,7 +79,7 @@ extension UIImageView { ...@@ -79,7 +79,7 @@ extension UIImageView {
options.progressHandler = { progress, error, stop, info in options.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async { DispatchQueue.main.async {
// 可以在这里添加加载进度的处理 // 可以在这里添加加载进度的处理
print("Loading progress: \(progress)") // print("Loading progress: \(progress)")
if let error = error { if let error = error {
print("Loading error: \(error.localizedDescription)") print("Loading error: \(error.localizedDescription)")
} }
......
...@@ -215,6 +215,7 @@ class PhotoManager{ ...@@ -215,6 +215,7 @@ class PhotoManager{
let start = CFAbsoluteTimeGetCurrent() let start = CFAbsoluteTimeGetCurrent()
self.videoModels = await convertAssetsToModel(for: self.videoAssets, mediaType: 2) self.videoModels = await convertAssetsToModel(for: self.videoAssets, mediaType: 2)
self.videoModels.sort { $0.createDate > $1.createDate }
let duration = CFAbsoluteTimeGetCurrent() - start let duration = CFAbsoluteTimeGetCurrent() - start
print("视频转换总耗时: \(duration)秒") print("视频转换总耗时: \(duration)秒")
let videoTotalSize = Int64(self.videoModels.reduce(0){$0+$1.assetSize}) let videoTotalSize = Int64(self.videoModels.reduce(0){$0+$1.assetSize})
...@@ -244,6 +245,7 @@ class PhotoManager{ ...@@ -244,6 +245,7 @@ class PhotoManager{
let start = CFAbsoluteTimeGetCurrent() let start = CFAbsoluteTimeGetCurrent()
self.otherModels = await convertAssetsToModel(for: self.otherAssets, mediaType: 1) self.otherModels = await convertAssetsToModel(for: self.otherAssets, mediaType: 1)
self.otherModels.sort { $0.createDate > $1.createDate }
let duration = CFAbsoluteTimeGetCurrent() - start let duration = CFAbsoluteTimeGetCurrent() - start
print("其他图片转换总耗时: \(duration)秒") print("其他图片转换总耗时: \(duration)秒")
let otherTotalSize = Int64(self.otherModels.reduce(0){$0+$1.assetSize}) let otherTotalSize = Int64(self.otherModels.reduce(0){$0+$1.assetSize})
...@@ -269,11 +271,11 @@ class PhotoManager{ ...@@ -269,11 +271,11 @@ class PhotoManager{
self.screenShotTotalSize = screenShotTotalSize self.screenShotTotalSize = screenShotTotalSize
complectionHandler?(localModels, screenShotTotalSize) complectionHandler?(localModels, screenShotTotalSize)
} }
return
} }
let start = CFAbsoluteTimeGetCurrent() let start = CFAbsoluteTimeGetCurrent()
self.screenShotModels = await convertAssetsToModel(for: self.screenShotAssets, mediaType: 1) self.screenShotModels = await convertAssetsToModel(for: self.screenShotAssets, mediaType: 1)
self.screenShotModels.sort { $0.createDate > $1.createDate }
let duration = CFAbsoluteTimeGetCurrent() - start let duration = CFAbsoluteTimeGetCurrent() - start
print("截图转换总耗时: \(duration)秒") print("截图转换总耗时: \(duration)秒")
let screenShotTotalSize = Int64(self.screenShotModels.reduce(0){$0+$1.assetSize}) let screenShotTotalSize = Int64(self.screenShotModels.reduce(0){$0+$1.assetSize})
......
...@@ -51,7 +51,7 @@ class HomeView:UIView { ...@@ -51,7 +51,7 @@ class HomeView:UIView {
sview.register(HomeTitleCollectionCell.self, forCellWithReuseIdentifier: HomeTitleCollectionCell.identifiers) sview.register(HomeTitleCollectionCell.self, forCellWithReuseIdentifier: HomeTitleCollectionCell.identifiers)
sview.register(HomeOtherCollectionCell.self, forCellWithReuseIdentifier: HomeOtherCollectionCell.identifier) sview.register(HomeOtherCollectionCell.self, forCellWithReuseIdentifier: HomeOtherCollectionCell.identifier)
sview.register(HomeVideoCoverCell.classForCoder(), forCellWithReuseIdentifier: "HomeVideoCoverCell")
sview.register(HomeCollectionViewHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HomeCollectionViewHeader") sview.register(HomeCollectionViewHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HomeCollectionViewHeader")
sview.register(UICollectionReusableView.self,forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,withReuseIdentifier: "HomeCollectionViewFooter") sview.register(UICollectionReusableView.self,forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,withReuseIdentifier: "HomeCollectionViewFooter")
...@@ -278,11 +278,19 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol ...@@ -278,11 +278,19 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol
return cell return cell
case 1: case 1:
if viewModel.cardGroup[indexPath.row].folderName == HomeUIEnum.SimilarVideos.title || viewModel.cardGroup[indexPath.row].folderName == HomeUIEnum.Videos.title{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeVideoCoverCell", for: indexPath) as! HomeVideoCoverCell
let model = viewModel.cardGroup[indexPath.row]
cell.reloadUIWithModel(model: model)
return cell
}else{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HomeOtherCollectionCell.identifier, for: indexPath) as! HomeOtherCollectionCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HomeOtherCollectionCell.identifier, for: indexPath) as! HomeOtherCollectionCell
cell.dealMediaType(indexPath.row) cell.dealMediaType(indexPath.row)
let model = viewModel.cardGroup[indexPath.row] let model = viewModel.cardGroup[indexPath.row]
cell.reloadUIWithModel(model: model) cell.reloadUIWithModel(model: model)
return cell return cell
}
default: default:
return UICollectionViewCell() return UICollectionViewCell()
} }
...@@ -402,9 +410,9 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol ...@@ -402,9 +410,9 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol
func referenceSizeForHeader(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGSize { func referenceSizeForHeader(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGSize {
if section == 0 { if section == 0 {
if PhotoManager.shared.permissionStatus == .authorized{ if PhotoManager.shared.permissionStatus == .authorized{
return CGSize(width: self.collectionView.width, height: 76 + (self.homeNavView?.height ?? 0)) return CGSize(width:ScreenW-(marginLR*2), height: 76 + (self.homeNavView?.height ?? 0))
}else{ }else{
return CGSize(width: self.collectionView.width, height: 450) return CGSize(width:ScreenW-(marginLR*2), height: 450)
} }
} }
return CGSize.zero return CGSize.zero
......
...@@ -12,7 +12,7 @@ class HomeTitleCollectionCell:UICollectionViewCell { ...@@ -12,7 +12,7 @@ class HomeTitleCollectionCell:UICollectionViewCell {
static let identifiers = "HomeTitleCollectionCellID" static let identifiers = "HomeTitleCollectionCellID"
private var titleLabel: UILabel? private var titleLabel: UILabel!
public var fileLabel:UILabel? public var fileLabel:UILabel?
...@@ -48,8 +48,8 @@ class HomeTitleCollectionCell:UICollectionViewCell { ...@@ -48,8 +48,8 @@ class HomeTitleCollectionCell:UICollectionViewCell {
titleLabel = UILabel() titleLabel = UILabel()
titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .bold) titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
titleLabel?.textColor = UIColor.colorWithHex(hexStr: black3Color) titleLabel.textColor = UIColor.colorWithHex(hexStr: black3Color)
fileLabel = UILabel() fileLabel = UILabel()
fileLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold) fileLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold)
...@@ -118,8 +118,8 @@ class HomeTitleCollectionCell:UICollectionViewCell { ...@@ -118,8 +118,8 @@ class HomeTitleCollectionCell:UICollectionViewCell {
guard let model = model else { return } guard let model = model else { return }
self.model = model self.model = model
titleLabel?.text = model.folderName titleLabel.text = model.folderName
titleLabel?.sizeToFit() titleLabel.sizeToFit()
var count = 0 var count = 0
...@@ -137,8 +137,8 @@ class HomeTitleCollectionCell:UICollectionViewCell { ...@@ -137,8 +137,8 @@ class HomeTitleCollectionCell:UICollectionViewCell {
assetsModels = assets.compactMap({ model in assetsModels = assets.compactMap({ model in
return ImageCollectionModel.init(asset: model) return ImageCollectionModel.init(asset: model)
}) })
collectionView?.reloadData()
} }
collectionView?.reloadData()
} }
...@@ -155,12 +155,12 @@ class HomeTitleCollectionCell:UICollectionViewCell { ...@@ -155,12 +155,12 @@ class HomeTitleCollectionCell:UICollectionViewCell {
super.layoutSubviews() super.layoutSubviews()
titleLabel?.snp.makeConstraints({ make in titleLabel.snp.makeConstraints({ make in
make.top.left.equalTo(16) make.top.left.equalTo(16)
}) })
titleLabel?.sizeToFit() titleLabel.sizeToFit()
fileLabel?.snp.makeConstraints({ make in fileLabel?.snp.makeConstraints({ make in
...@@ -172,9 +172,9 @@ class HomeTitleCollectionCell:UICollectionViewCell { ...@@ -172,9 +172,9 @@ class HomeTitleCollectionCell:UICollectionViewCell {
collectionView?.snp.makeConstraints({ make in collectionView?.snp.makeConstraints({ make in
make.left.equalTo(16) make.left.equalTo(16)
make.bottom.equalTo(-16) make.bottom.equalTo(0)
make.right.equalTo(-16) make.right.equalTo(-16)
make.top.equalTo(48) make.top.equalTo(titleLabel.snp.bottom).offset(13)
}) })
nextImage?.snp.makeConstraints({ make in nextImage?.snp.makeConstraints({ make in
...@@ -205,7 +205,7 @@ extension HomeTitleCollectionCell:UICollectionViewDelegate,UICollectionViewDataS ...@@ -205,7 +205,7 @@ extension HomeTitleCollectionCell:UICollectionViewDelegate,UICollectionViewDataS
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// 计算 cell 宽度 // 计算 cell 宽度
return CGSize(width:collectionView.height - 2.5, height: collectionView.height - 2.5) // 宽高相等,形成网格 return CGSize(width:collectionView.height - 18, height: collectionView.height - 18) // 宽高相等,形成网格
} }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
......
//
// HomeVideoCoverCell.swift
// PhoneManager
//
// Created by edy on 2025/5/20.
//
import UIKit
import AVKit
class HomeVideoCoverCell: UICollectionViewCell {
var videoUrl:URL?
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
backgroundColor = .white
self.contentView.addSubview(self.titleLabel)
self.contentView.addSubview(self.imageView)
contentView.layer.addSublayer(playerLayer)
self.contentView.addSubview(self.infoBackView)
self.infoBackView.addSubview(self.countLabel)
self.infoBackView.addSubview(self.sizeLabel)
self.infoBackView.addSubview(self.moreImageView)
}
func reloadUIWithModel(model:HomePhotosModel?){
// 1. 先重置状态
guard let model else {
playerLayer.isHidden = true
videoPlayer.pause()
return
}
// 设置标题
self.titleLabel.text = model.folderName
// 获取数量
var count = 0
for item in model.assets {
count = count + item.count
}
// 设置数量文字
self.countLabel.text = "\(count) Videos"
// 设置文件大小文字
let sizeKB : Double = model.allFileSize/1000
if sizeKB < 1000{
self.sizeLabel.text = String(format: "(%.2lf) KB" ,sizeKB)
}else if sizeKB < (1000 * 1000) && sizeKB > 1000{
self.sizeLabel.text = String(format: "(%.2lf) MB" ,sizeKB/1000)
}else{
self.sizeLabel.text = String(format: "(%.2lf) GB" ,sizeKB/(1000 * 1000))
}
// 2. 设置新数据
if let id = model.assets.first?.first?.localIdentifier{
// 保存当前的 identifier 用于验证
let currentID = id
imageView.asset.load(withLocalIdentifier:id,placeholder: UIImage(named: "videosmoren"))
PhotoManager.shared.getVideoURL(localIdentifier:id, completion: {[weak self] url in
guard let weakSelf = self else { return }
// 验证 ID 是否匹配,避免 cell 重用导致的错误
if currentID == id {
weakSelf.configure(with: url)
}
})
}else{
self.imageView.image = UIImage.init(named: "videosmoren")
playerLayer.isHidden = true
videoPlayer.pause()
}
}
public let imageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 8
iv.backgroundColor = .clear
return iv
}()
private let infoBackView: UIView = {
let iv = UIView()
iv.clipsToBounds = true
iv.layer.cornerRadius = 8
iv.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
return iv
}()
public var countLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 14, weight: .medium)
label.textAlignment = .left
return label
}()
let sizeLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 10, weight: .medium)
label.textAlignment = .left
return label
}()
private let moreImageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.image = UIImage(named: "icon_left_setting_grey")
iv.backgroundColor = .clear
return iv
}()
private let titleLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 16, weight: .bold)
label.textColor = UIColor.colorWithHex(hexStr: black3Color)
label.textAlignment = .left
label.numberOfLines = 0
return label
}()
override func layoutSubviews() {
self.layer.cornerRadius = 12
self.layer.masksToBounds = true
imageView.snp.makeConstraints { make in
make.top.equalTo(self.titleLabel.snp.bottom).offset(8)
make.left.equalToSuperview().offset(16)
make.width.equalToSuperview().offset(-32)
make.height.equalTo(self.width - 32)
}
self.infoBackView.snp.makeConstraints { make in
make.left.right.bottom.equalTo(imageView)
make.height.equalTo(40)
}
titleLabel.snp.makeConstraints { make in
make.left.top.equalToSuperview().offset(16)
make.width.equalToSuperview().offset(-32)
}
self.countLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalToSuperview().offset(3)
make.height.equalTo(20)
}
self.sizeLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalTo(countLabel.snp.bottom).offset(-2)
make.height.equalTo(14)
}
self.moreImageView.snp.makeConstraints { make in
make.width.height.equalTo(20)
make.right.equalToSuperview().offset(-12)
make.centerY.equalToSuperview()
}
playerLayer.frame = imageView.frame
playerLayer.cornerRadius = 8
playerLayer.masksToBounds = true
}
lazy var videoPlayer:AVPlayer = {
let palyer = AVPlayer.init()
palyer.volume = 0
// 设置音频会话,允许混音
try? AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers)
try? AVAudioSession.sharedInstance().setActive(true)
return palyer
}()
lazy var playerLayer:AVPlayerLayer = {
let playerLayer = AVPlayerLayer.init(player: videoPlayer)
playerLayer.backgroundColor = UIColor.black.cgColor
playerLayer.isHidden = true
return playerLayer
}()
deinit{
NotificationCenter.default.removeObserver(self)
}
}
extension HomeVideoCoverCell{
func configure(with videoURL: URL?) {
guard let videoURL = videoURL else{
playerLayer.isHidden = true
videoPlayer.pause()
return
}
playerLayer.isHidden = false
if videoURL == videoUrl{
Print("地址相同,无需刷新")
return
}
videoUrl = videoURL
Print("地址不同,需刷新")
let item = AVPlayerItem.init(url: videoURL)
videoPlayer.replaceCurrentItem(with: item)
videoPlayer.play()
NotificationCenter.default.addObserver(self,
selector: #selector(playerDidFinishPlaying),
name: .AVPlayerItemDidPlayToEndTime,
object: item)
}
@objc private func playerDidFinishPlaying() {
videoPlayer.seek(to: .zero)
videoPlayer.play()
}
}
...@@ -80,6 +80,7 @@ class MaintaiDetailViewController: BaseViewController { ...@@ -80,6 +80,7 @@ class MaintaiDetailViewController: BaseViewController {
if isSelectAll{ if isSelectAll{
let ids = viewModel.souces.flatMap{$0}.compactMap{$0.localIdentifier} let ids = viewModel.souces.flatMap{$0}.compactMap{$0.localIdentifier}
if GroupDatabase.shared.batchDelete(localIdentifiers: ids){ if GroupDatabase.shared.batchDelete(localIdentifiers: ids){
selectAsset.removeAll()
self.navigationController?.popViewController(animated: true) self.navigationController?.popViewController(animated: true)
} }
isSelectAll = false isSelectAll = false
...@@ -175,7 +176,7 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{ ...@@ -175,7 +176,7 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{
} }
// 拿到当前在选中数据的下标 // 拿到当前在选中数据的下标
let selectIndex = selectAsset.firstIndex(where: { var selectIndex = selectAsset.firstIndex(where: {
$0 == cell.selectAsset $0 == cell.selectAsset
}) })
...@@ -191,11 +192,15 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{ ...@@ -191,11 +192,15 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{
weakSelf.selectAsset[sIndex] = selects weakSelf.selectAsset[sIndex] = selects
}else{ }else{
weakSelf.selectAsset.remove(at: sIndex) weakSelf.selectAsset.remove(at: sIndex)
selectIndex = nil
} }
}else{ }else{
Print("没有任何选中数据") Print("没有任何选中数据")
weakSelf.selectAsset.append(selects) weakSelf.selectAsset.append(selects)
selectIndex = weakSelf.selectAsset.firstIndex(where: {
$0 == selects
})
} }
weakSelf.dealMutilImagePick() weakSelf.dealMutilImagePick()
} }
...@@ -238,8 +243,10 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{ ...@@ -238,8 +243,10 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{
}else{ }else{
maintaiBottomView.disMiss() maintaiBottomView.disMiss()
} }
// tableView.reloadData()
tableView.reloadData() // UIView.performWithoutAnimation {
// self.tableView.reloadData()
// }
} }
func dealPickAssetModel(index:Int){ func dealPickAssetModel(index:Int){
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
<rect key="frame" x="0.0" y="0.0" width="269" height="253"/> <rect key="frame" x="0.0" y="0.0" width="269" height="253"/>
</imageView> </imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oJ5-js-pjw"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oJ5-js-pjw">
<rect key="frame" x="234" y="213" width="30" height="30"/> <rect key="frame" x="235" y="219" width="34" height="34"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="30" id="gGs-ha-T24"/> <constraint firstAttribute="width" constant="34" id="gGs-ha-T24"/>
<constraint firstAttribute="height" constant="30" id="mvi-bY-CFY"/> <constraint firstAttribute="height" constant="34" id="mvi-bY-CFY"/>
</constraints> </constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="icon_maintai_unselect_big"/> <state key="normal" image="icon_maintai_unselect_big"/>
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
<viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/> <viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/>
<constraints> <constraints>
<constraint firstAttribute="bottom" secondItem="T4a-zL-UKQ" secondAttribute="bottom" id="B7R-M8-dpU"/> <constraint firstAttribute="bottom" secondItem="T4a-zL-UKQ" secondAttribute="bottom" id="B7R-M8-dpU"/>
<constraint firstAttribute="bottom" secondItem="oJ5-js-pjw" secondAttribute="bottom" constant="10" id="BfF-Td-Tcc"/> <constraint firstAttribute="bottom" secondItem="oJ5-js-pjw" secondAttribute="bottom" id="BfF-Td-Tcc"/>
<constraint firstAttribute="trailing" secondItem="oJ5-js-pjw" secondAttribute="trailing" constant="5" id="Iw9-UA-zNe"/> <constraint firstAttribute="trailing" secondItem="oJ5-js-pjw" secondAttribute="trailing" id="Iw9-UA-zNe"/>
<constraint firstItem="T4a-zL-UKQ" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="MoV-lR-Hqz"/> <constraint firstItem="T4a-zL-UKQ" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="MoV-lR-Hqz"/>
<constraint firstItem="T4a-zL-UKQ" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="dJs-Pa-MhO"/> <constraint firstItem="T4a-zL-UKQ" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="dJs-Pa-MhO"/>
<constraint firstAttribute="trailing" secondItem="T4a-zL-UKQ" secondAttribute="trailing" id="gyj-E3-guF"/> <constraint firstAttribute="trailing" secondItem="T4a-zL-UKQ" secondAttribute="trailing" id="gyj-E3-guF"/>
......
...@@ -43,7 +43,7 @@ class MaintaiDetailImageSmallCell: UICollectionViewCell { ...@@ -43,7 +43,7 @@ class MaintaiDetailImageSmallCell: UICollectionViewCell {
selectBtn.addTarget(self, action: #selector(selectChange), for: .touchUpInside) selectBtn.addTarget(self, action: #selector(selectChange), for: .touchUpInside)
selectBtn.snp.makeConstraints { make in selectBtn.snp.makeConstraints { make in
make.right.bottom.equalTo(0) make.right.bottom.equalTo(0)
make.size.equalTo(20) make.size.equalTo(30)
} }
} }
......
...@@ -58,8 +58,8 @@ class MaintaiDetailTableViewCell: UITableViewCell { ...@@ -58,8 +58,8 @@ class MaintaiDetailTableViewCell: UITableViewCell {
func configChild(){ func configChild(){
let layout = UICollectionViewFlowLayout() let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: smallW, height: smallW) layout.itemSize = CGSize(width: smallW, height: smallW)
layout.minimumLineSpacing = 8 layout.minimumLineSpacing = 12
layout.minimumInteritemSpacing = 8 layout.minimumInteritemSpacing = 12
layout.sectionInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12) layout.sectionInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
layout.scrollDirection = .horizontal layout.scrollDirection = .horizontal
...@@ -135,8 +135,9 @@ extension MaintaiDetailTableViewCell:UIScrollViewDelegate{ ...@@ -135,8 +135,9 @@ extension MaintaiDetailTableViewCell:UIScrollViewDelegate{
Print("主图滑动距离",scrollView.contentOffset.x) Print("主图滑动距离",scrollView.contentOffset.x)
let index = Int(scrollView.contentOffset.x/bigW) let index = Int(scrollView.contentOffset.x/bigW)
Print("小图滑动到下标\(index)") Print("小图滑动到下标\(index)")
let space:CGFloat = (self.smallW + 12) * CGFloat(index)
UIView.animate(withDuration: 0.3) { UIView.animate(withDuration: 0.3) {
self.pageCollectionView.contentOffset = CGPoint(x: index * Int(self.smallW+8)+4, y: 0) self.pageCollectionView.contentOffset = CGPoint(x:space, y: 0)
} }
} }
} }
...@@ -183,8 +184,9 @@ extension MaintaiDetailTableViewCell:UIScrollViewDelegate{ ...@@ -183,8 +184,9 @@ extension MaintaiDetailTableViewCell:UIScrollViewDelegate{
Print("小图滑动距离",offsetX) Print("小图滑动距离",offsetX)
let index = Int((offsetX/(smallW+12)).rounded()) //Int(offsetX/(smallW+12).rounded()) //rounded(offsetX/smallW) let index = Int((offsetX/(smallW+12)).rounded()) //Int(offsetX/(smallW+12).rounded()) //rounded(offsetX/smallW)
Print("大图滑动到下标\(index)") Print("大图滑动到下标\(index)")
let space:CGFloat = (self.smallW + 12) * CGFloat(index)
UIView.animate(withDuration: 0.3) { UIView.animate(withDuration: 0.3) {
self.pageCollectionView.contentOffset = CGPoint(x: index * Int(self.smallW+8)+4, y: 0) self.pageCollectionView.contentOffset = CGPoint(x: space, y: 0)
} }
self.mainCollectionView.contentOffset = CGPoint(x: index * Int(self.bigW), y: 0) self.mainCollectionView.contentOffset = CGPoint(x: index * Int(self.bigW), y: 0)
draggView = .null draggView = .null
......
...@@ -37,23 +37,20 @@ class MaintaiDetialVideoCell: UITableViewCell { ...@@ -37,23 +37,20 @@ class MaintaiDetialVideoCell: UITableViewCell {
contentView.bringSubviewToFront(selectBtn) contentView.bringSubviewToFront(selectBtn)
selectBtn.addTarget(self, action: #selector(selectChange), for: .touchUpInside) selectBtn.addTarget(self, action: #selector(selectChange), for: .touchUpInside)
selectBtn.snp.makeConstraints { make in selectBtn.snp.makeConstraints { make in
make.right.equalTo(-15) make.right.equalTo(-22)
make.bottom.equalTo(-10) make.bottom.equalTo(0)
make.size.equalTo(30) make.size.equalTo(34)
} }
} }
private func setupPlayer() { private func setupPlayer() {
// 创建播放器层
// playerLayer = AVPlayerLayer()
// playerLayer?.videoGravity = .resizeAspect
contentView.layer.addSublayer(playerLayer) contentView.layer.addSublayer(playerLayer)
} }
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
// 设置播放器层的frame // 设置播放器层的frame
playerLayer.frame = CGRect(x: 15, y: 10, width: contentView.width-30, height: contentView.height-20) playerLayer.frame = CGRect(x: 22, y: 10, width: contentView.width-44, height: contentView.height-10)
playerLayer.cornerRadius = 15 playerLayer.cornerRadius = 15
playerLayer.masksToBounds = true playerLayer.masksToBounds = true
} }
...@@ -92,7 +89,9 @@ class MaintaiDetialVideoCell: UITableViewCell { ...@@ -92,7 +89,9 @@ class MaintaiDetialVideoCell: UITableViewCell {
return return
} }
if videoPlayer.rate != 0{
return
}
let item = AVPlayerItem.init(url: videoURL) let item = AVPlayerItem.init(url: videoURL)
...@@ -100,45 +99,24 @@ class MaintaiDetialVideoCell: UITableViewCell { ...@@ -100,45 +99,24 @@ class MaintaiDetialVideoCell: UITableViewCell {
videoPlayer.play() videoPlayer.play()
// // 创建播放器项
// let playerItem = AVPlayerItem(url: videoURL)
//
// // 创建播放器
// player = AVPlayer(playerItem: playerItem)
// playerLayer?.player = player
//
// // 设置静音
// player?.volume = 0
//
// // 播放视频
// player?.play()
//
// 添加播放完成的观察者
NotificationCenter.default.addObserver(self, NotificationCenter.default.addObserver(self,
selector: #selector(playerDidFinishPlaying), selector: #selector(playerDidFinishPlaying),
name: .AVPlayerItemDidPlayToEndTime, name: .AVPlayerItemDidPlayToEndTime,
object: item) object: item)
} }
//
@objc private func playerDidFinishPlaying() { @objc private func playerDidFinishPlaying() {
// // 播放结束后不做任何操作,因为只需要播放一次
// player?.pause()
// player?.seek(to: .zero)
//playerLayer.player?.seek(to: .zero)
videoPlayer.seek(to: .zero) videoPlayer.seek(to: .zero)
videoPlayer.play() videoPlayer.play()
} }
//
// override func prepareForReuse() {
// super.prepareForReuse()
// // 清理播放器
// player?.pause()
// player = nil
// NotificationCenter.default.removeObserver(self)
// }
//
@objc func selectChange(){ @objc func selectChange(){
selectChangeBlock?() selectChangeBlock?()
} }
deinit{
NotificationCenter.default.removeObserver(self)
}
} }
...@@ -46,8 +46,11 @@ class HomePayDueView: UIView { ...@@ -46,8 +46,11 @@ class HomePayDueView: UIView {
func reloadUI(_ type:Int,week:SKProduct?,life:SKProduct?){ func reloadUI(_ type:Int,week:SKProduct?,life:SKProduct?){
guard let pord = week,let pord1 = life else { return } guard let pord = week,let pord1 = life else {
self.isHidden = true
return
}
self.isHidden = false
if type == 0{ if type == 0{
// 免费试用订阅 // 免费试用订阅
dueDay.text = "Due today" dueDay.text = "Due today"
......
...@@ -181,6 +181,7 @@ class HomePayView:UIView { ...@@ -181,6 +181,7 @@ class HomePayView:UIView {
payButton?.setTitleColor(UIColor.colorWithHex(hexStr: whiteColor), for: .normal) payButton?.setTitleColor(UIColor.colorWithHex(hexStr: whiteColor), for: .normal)
payButton?.titleLabel?.font = UIFont.scaledSystemFont(ofSize: 16, weight: .bold) payButton?.titleLabel?.font = UIFont.scaledSystemFont(ofSize: 16, weight: .bold)
payButton?.backgroundColor = UIColor.colorWithHex(hexStr: mColor) payButton?.backgroundColor = UIColor.colorWithHex(hexStr: mColor)
payButton?.isEnabled = false
payButton?.addTarget(self, action: #selector(payButtonClick), for: .touchUpInside) payButton?.addTarget(self, action: #selector(payButtonClick), for: .touchUpInside)
self.addSubview(payButton!) self.addSubview(payButton!)
...@@ -314,6 +315,13 @@ class HomePayView:UIView { ...@@ -314,6 +315,13 @@ class HomePayView:UIView {
self.weekProduct = week self.weekProduct = week
self.lifeProduct = life self.lifeProduct = life
if week != nil,life != nil{
payButton?.isEnabled = true
}else{
payButton?.isEnabled = false
}
payDueView.reloadUI(type, week: week, life: life) payDueView.reloadUI(type, week: week, life: life)
trailTitle.attributedText = nil trailTitle.attributedText = nil
...@@ -413,7 +421,7 @@ class HomePayView:UIView { ...@@ -413,7 +421,7 @@ class HomePayView:UIView {
} }
trailTitle = UILabel() trailTitle = UILabel()
trailTitle.text = "Free for 7 days, then $6.99/week" trailTitle.text = "" //"Free for 7 days, then $6.99/week"
trailTitle.textColor = UIColor.colorWithHex(hexStr: black3Color) trailTitle.textColor = UIColor.colorWithHex(hexStr: black3Color)
trailTitle.font = UIFont.scaledSystemFont(ofSize: 12, weight: .regular) trailTitle.font = UIFont.scaledSystemFont(ofSize: 12, weight: .regular)
tipsView.addSubview(trailTitle) tipsView.addSubview(trailTitle)
......
...@@ -21,6 +21,7 @@ class PayDistanceViewController: UIViewController { ...@@ -21,6 +21,7 @@ class PayDistanceViewController: UIViewController {
var payBtn:UIButton! var payBtn:UIButton!
var year:SKProduct? var year:SKProduct?
var life:SKProduct?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -70,14 +71,14 @@ class PayDistanceViewController: UIViewController { ...@@ -70,14 +71,14 @@ class PayDistanceViewController: UIViewController {
yearDistacePrice = UILabel() yearDistacePrice = UILabel()
yearDistacePrice.font = UIFont.systemFont(ofSize: 14,weight: .semibold) yearDistacePrice.font = UIFont.systemFont(ofSize: 14,weight: .semibold)
yearDistacePrice.textColor = UIColor.colorWithHex(hexStr: "#111111") yearDistacePrice.textColor = UIColor.colorWithHex(hexStr: "#111111")
yearDistacePrice.text = "$39.99 $19.99 / Year" yearDistacePrice.text = ""//"$39.99 $19.99 / Year"
scrollView.addSubview(yearDistacePrice) scrollView.addSubview(yearDistacePrice)
let priceAtt = createRichPriceText( // let priceAtt = createRichPriceText(
originalPrice: "$39.99", // originalPrice: "$39.99",
discountedPrice: "$19.99 / Year" // discountedPrice: "$19.99 / Year"
) // )
yearDistacePrice.attributedText = priceAtt // yearDistacePrice.attributedText = priceAtt
let cancelLabel = UILabel() let cancelLabel = UILabel()
cancelLabel.font = UIFont.systemFont(ofSize: 12,weight: .semibold) cancelLabel.font = UIFont.systemFont(ofSize: 12,weight: .semibold)
...@@ -90,13 +91,14 @@ class PayDistanceViewController: UIViewController { ...@@ -90,13 +91,14 @@ class PayDistanceViewController: UIViewController {
payBtn.setTitleColor(.white, for: .normal) payBtn.setTitleColor(.white, for: .normal)
payBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold) payBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
payBtn.layer.cornerRadius = 30 payBtn.layer.cornerRadius = 30
payBtn.isEnabled = false
payBtn.addTarget(self, action: #selector(iapPayAction), for: .touchUpInside) payBtn.addTarget(self, action: #selector(iapPayAction), for: .touchUpInside)
payBtn.backgroundColor = UIColor.colorWithHex(hexStr: "#0082FF") payBtn.backgroundColor = UIColor.colorWithHex(hexStr: "#0082FF")
scrollView.addSubview(payBtn) scrollView.addSubview(payBtn)
let termsBtn = UIButton() let termsBtn = UIButton()
termsBtn.setTitle("Terms", for: .normal) termsBtn.setTitle("Terms", for: .normal)
termsBtn.titleLabel?.font = UIFont.systemFont(ofSize: 10,weight: .medium) termsBtn.titleLabel?.font = UIFont.systemFont(ofSize: 11.RW(),weight: .medium)
termsBtn.setTitleColor(UIColor.colorWithHex(hexStr: "#999999"), for: .normal) termsBtn.setTitleColor(UIColor.colorWithHex(hexStr: "#999999"), for: .normal)
termsBtn.titleLabel?.addUnderline() termsBtn.titleLabel?.addUnderline()
termsBtn.addTarget(self, action: #selector(termsAction(btn:)), for: .touchUpInside) termsBtn.addTarget(self, action: #selector(termsAction(btn:)), for: .touchUpInside)
...@@ -106,9 +108,9 @@ class PayDistanceViewController: UIViewController { ...@@ -106,9 +108,9 @@ class PayDistanceViewController: UIViewController {
let recoveryBtn = UIButton() let recoveryBtn = UIButton()
recoveryBtn.setTitle("Restore", for: .normal) recoveryBtn.setTitle("Restore", for: .normal)
recoveryBtn.titleLabel?.font = UIFont.systemFont(ofSize: 10,weight: .medium) recoveryBtn.titleLabel?.font = UIFont.systemFont(ofSize: 11.RW(),weight: .medium)
recoveryBtn.setTitleColor(UIColor.colorWithHex(hexStr: "#999999"), for: .normal) recoveryBtn.setTitleColor(UIColor.colorWithHex(hexStr: "#999999"), for: .normal)
recoveryBtn.frame = CGRect(x: scrollView.bounds.width - 66, y: ScreenH - (20+kSafeAreaInsets.bottom), width: 50, height: 20) recoveryBtn.frame = CGRect(x: scrollView.bounds.width - 66, y: ScreenH - (20+kSafeAreaInsets.bottom), width: CGFloat(50.RW()), height: 20)
recoveryBtn.titleLabel?.addUnderline() recoveryBtn.titleLabel?.addUnderline()
recoveryBtn.addTarget(self, action: #selector(recoveryBtnAction), for: .touchUpInside) recoveryBtn.addTarget(self, action: #selector(recoveryBtnAction), for: .touchUpInside)
scrollView.addSubview(recoveryBtn) scrollView.addSubview(recoveryBtn)
...@@ -256,8 +258,9 @@ class PayDistanceViewController: UIViewController { ...@@ -256,8 +258,9 @@ class PayDistanceViewController: UIViewController {
IAPManager.share.fetchProducts { [weak self] products in IAPManager.share.fetchProducts { [weak self] products in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
DispatchQueue.main.async { DispatchQueue.main.async {
if let (_, _,yearProduct) = products { if let (_,lifetimeProduct,yearProduct) = products {
weakSelf.year = yearProduct weakSelf.year = yearProduct
weakSelf.life = lifetimeProduct
weakSelf.reloadSKUI() weakSelf.reloadSKUI()
} }
} }
...@@ -266,12 +269,13 @@ class PayDistanceViewController: UIViewController { ...@@ -266,12 +269,13 @@ class PayDistanceViewController: UIViewController {
func reloadSKUI(){ func reloadSKUI(){
guard let year = year else{ guard let year = year,let life = life else{
payBtn.isEnabled = false
return return
} }
payBtn.isEnabled = true
let priceAtt = createRichPriceText( let priceAtt = createRichPriceText(
originalPrice: "$39.99", originalPrice: "\(life.localizedPrice)",
discountedPrice: "\(year.localizedPrice) / Year" discountedPrice: "\(year.localizedPrice) / Year"
) )
yearDistacePrice.attributedText = priceAtt yearDistacePrice.attributedText = priceAtt
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment