Commit 87820404 authored by CZ1004's avatar CZ1004

【优化】压缩

parent 9b23744d
{
"images" : [
{
"filename" : "Group.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "Group_1171275114.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group_1171275114@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group_1171275114@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "* 白色实心圆-小.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "* 白色实心圆-小@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "* 白色实心圆-小@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
......@@ -69,17 +69,6 @@ class CompressSelectCell : UICollectionViewCell {
}
}
var choose : Bool = false {
didSet{
if choose {
self.selectImageView.image = UIImage(named: "ic_unsel_com")
}else{
self.selectImageView.image = UIImage(named: "ic_sel_com")
}
callBack(self.model! ,self.choose)
}
}
lazy var backImageView: UIImageView = {
let view = UIImageView()
......@@ -125,59 +114,14 @@ class CompressSelectCell : UICollectionViewCell {
return view
}()
lazy var extensionView: UIView = {
let view = UIView()
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(selectClick))
view.addGestureRecognizer(tap)
return view
}()
lazy var selectImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_sel_com")
view.backgroundColor = .clear
view.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(selectClick))
view.addGestureRecognizer(tap)
return view
}()
@objc func selectClick(){
// 判断是图片还是视频
if self.currentMediaType == .compressPhoto {
self.choose = !self.choose
}else {
let vc = PMShowImgVideoController()
vc.getVideoURLFromLocalIdentifier(localIdentifier: self.model?.localIdentifier ?? "") {[weak self] url, error in
guard let self else {return}
if url != nil{
self.choose = !self.choose
}else{
let alert = UIAlertController(title: nil, message: "ICloud video cannot be compressed", preferredStyle: .alert)
self.responderViewController()?.present(alert, animated: true, completion: nil)
// 1 秒后关闭弹窗
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
}
}
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(imageClick))
self.addGestureRecognizer(tap)
// self.isUserInteractionEnabled = true
// let tap = UITapGestureRecognizer()
// tap.addTarget(self, action: #selector(imageClick))
// self.addGestureRecognizer(tap)
self.addSubview(self.backImageView)
self.backImageView.addSubview(self.playImageView)
......@@ -185,9 +129,6 @@ class CompressSelectCell : UICollectionViewCell {
self.saveSizeView.addSubview(self.saveSizeLabel)
self.saveSizeView.addSubview(self.moreImageView)
self.addSubview(self.extensionView)
self.addSubview(self.selectImageView)
self.backImageView.snp.makeConstraints { make in
make.left.right.height.width.equalToSuperview()
}
......@@ -214,16 +155,6 @@ class CompressSelectCell : UICollectionViewCell {
make.height.width.equalTo(16)
}
self.selectImageView.snp.makeConstraints { make in
make.bottom.right.equalToSuperview().offset(-12)
make.height.width.equalTo(24)
}
self.extensionView.snp.makeConstraints { make in
make.center.equalTo(self.selectImageView.snp.center)
make.height.width.equalTo(80)
}
}
required init?(coder: NSCoder) {
......@@ -231,89 +162,9 @@ class CompressSelectCell : UICollectionViewCell {
}
@objc func imageClick(){
if self.currentMediaType == .compressPhoto {
// 点击之后跳转详情页面
if let tempModel = self.model {
let vc = PMShowImgVideoController()
vc.state = .similarPhotos
vc.currentIdx = 0
vc.oldPageIndexPath = indexPath
let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = self.choose
dataSource.id = tempModel
// 获取image
dataSource.image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: tempModel.localIdentifier)
vc.homeDataSource = [dataSource]
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
if let data = data{
if let item = data.first{
self.choose = item.isSeleted ?? false
}
}
}
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
}
}else{
// 如果是视频
if let tempModel = self.model {
// 获取视频的图片
PhotoAndVideoMananger.mananger.getVideoImageByIdent(ident: tempModel) { image in
// 点击之后跳转详情页面
let vc = PMShowImgVideoController()
vc.state = .similarVideos
vc.currentIdx = 0
vc.oldPageIndexPath = self.indexPath
let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = self.choose
dataSource.id = tempModel
dataSource.image = image
// 表示这个是视频
vc.homeDataSource = [dataSource]
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
if let data = data{
if let item = data.first{
self.choose = item.isSeleted ?? false
}
}
}
vc.getVideoURLFromLocalIdentifier(localIdentifier: tempModel.localIdentifier) { url, error in
if url != nil{
DispatchQueue.main.async {
vc.url = url
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
}
}else{
let alert = UIAlertController(title: nil, message: "ICloud video cannot be viewed", preferredStyle: .alert)
self.responderViewController()?.present(alert, animated: true, completion: nil)
// 2 秒后关闭弹窗
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
}
}
}
} errorHandler: {
DispatchQueue.main.async {
let alert = UIAlertController(title: nil, message: "Get Video image failure", preferredStyle: .alert)
self.responderViewController()?.navigationController?.present(alert, animated: true)
// 1秒之后消失
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
self.responderViewController()?.navigationController?.popViewController(animated: true)
}
}
}
}
}
}
// @objc func imageClick(){
//
//
// }
}
......@@ -11,79 +11,105 @@ import Lottie
class CompressCompletedViewController : BaseViewController{
var model : [AssetModel]?
// MARK: 属性
var model : AssetModel?
var comDataSource : [Data] = []
var comDataSource : [Data] = [] {
didSet{
if let data = comDataSource.first{
DispatchQueue.main.async {
self.preImageView.image = UIImage(data: data)
self.infoView.isHidden = true
}
}
}
}
var comVideoDataSource : [URL?] = []
var comVideoDataSource : [URL?] = []{
didSet{
if let url = comVideoDataSource.first{
DispatchQueue.main.async {
self.infoView.playVideo(from: url)
self.preImageView.isHidden = true
}
}
}
}
var currentMediaType : CompressType = .compressPhoto
var currentMediaType : CompressType = .compressPhoto {
didSet{
if currentMediaType == .compressPhoto {
self.deleteButton.setTitle("Delete the original photo", for: .normal)
self.keepButton.setTitle("Keep two photos", for: .normal)
}else {
self.deleteButton.setTitle("Delete the original video", for: .normal)
self.keepButton.setTitle("Keep two videos", for: .normal)
}
}
}
lazy var bacView : UIView = {
let view = UIView()
view.layer.cornerRadius = 115
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
return view
}()
var completedSize : Double = 0.0 {
didSet{
DispatchQueue.main.async {
if let model = self.model {
self.sizeToplabel.text = formatFileSize(model.assetSize - self.completedSize)
}
}
}
}
lazy var animationView : LottieAnimationView = {
let animationView = LottieAnimationView(name: "iOS压缩完成")
animationView.layer.cornerRadius = 12
animationView.backgroundColor = .clear
animationView.loopMode = .loop
return animationView
}()
// MARK: 懒加载
lazy var topImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "Group")
return view
}()
lazy var tipLabel: UILabel = {
let label = UILabel()
label.text = "Congratulations!"
label.textAlignment = .center
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 20, weight: .bold)
label.font = UIFont.systemFont(ofSize: 20, weight: .semibold)
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "You've cleaned your phone"
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.text = "Preview"
label.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
label.backgroundColor = .clear
return label
}()
lazy var infoView: UIView = {
let view = UIView()
lazy var infoView: SecretVideoPlayer = {
let view = SecretVideoPlayer()
view.backgroundColor = .white
view.clipsToBounds = true
view.layer.cornerRadius = 12
return view
}()
lazy var topImageView: UIImageView = {
lazy var preImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_compressed_end")
view.layer.cornerRadius = 12
view.contentMode = .scaleAspectFit
view.clipsToBounds = true
return view
}()
lazy var tipTopLabel: UILabel = {
let label = UILabel()
label.text = "Compressed"
label.textAlignment = .left
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTipToplabel: UILabel = {
lazy var tipTopLabel: UILabel = {
let label = UILabel()
label.text = "2 items"
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.text = "You have saved a total after compression"
label.textAlignment = .center
label.textColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .medium)
label.backgroundColor = .clear
return label
}()
......@@ -91,187 +117,117 @@ class CompressCompletedViewController : BaseViewController{
let label = UILabel()
label.text = "511MB"
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.textAlignment = .right
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.layer.borderColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 20, weight: .medium)
label.backgroundColor = .clear
return label
}()
lazy var bottomImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_freed_end")
lazy var keepButton : UIButton = {
let view = UIButton()
view.setTitle("Keep two videos", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
view.clipsToBounds = true
view.layer.cornerRadius = 25.5
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
view.addTarget(self, action: #selector(keepButtonAction), for: .touchUpInside)
return view
}()
lazy var tipBottomLabel: UILabel = {
let label = UILabel()
label.text = "Compressed"
label.textAlignment = .left
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTipBottomlabel: UILabel = {
let label = UILabel()
label.text = "2 items"
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var sizeBottomlabel: UILabel = {
let label = UILabel()
label.text = "1.0%"
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.textAlignment = .right
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.layer.borderColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
label.backgroundColor = .clear
return label
}()
lazy var finalTipLabel: UILabel = {
let label = UILabel()
label.text = "To free up storage permanently or recover media, go to the“Recently Deleted“ album on your device."
label.textColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1)
label.textAlignment = .center
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var completedButton : UIButton = {
lazy var deleteButton : UIButton = {
let view = UIButton()
view.setTitle("Compress", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.setTitle("Delete the original photo", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1), for: .normal)
view.clipsToBounds = true
view.layer.cornerRadius = 23
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
view.addTarget(self, action: #selector(completedAction), for: .touchUpInside)
view.layer.cornerRadius = 25.5
view.backgroundColor = .clear
view.addTarget(self, action: #selector(deleteButtonAction), for: .touchUpInside)
return view
}()
func setUI(){
// MARK: 系统方法
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.titleView.isHidden = true
self.view.addSubview(self.bacView)
self.view.addSubview(self.animationView)
self.setUI()
}
// MARK: 设置UI
func setUI(){
self.view.addSubview(self.topImageView)
self.view.addSubview(self.tipLabel)
self.view.addSubview(self.detailTiplabel)
self.view.addSubview(self.infoView)
self.infoView.addSubview(self.topImageView)
self.infoView.addSubview(self.tipTopLabel)
self.infoView.addSubview(self.detailTipToplabel)
self.infoView.addSubview(self.sizeToplabel)
self.infoView.addSubview(self.bottomImageView)
self.infoView.addSubview(self.tipBottomLabel)
self.infoView.addSubview(self.detailTipBottomlabel)
self.infoView.addSubview(self.sizeBottomlabel)
self.infoView.addSubview(self.finalTipLabel)
self.view.addSubview(self.completedButton)
self.view.addSubview(self.preImageView)
self.view.addSubview(self.tipTopLabel)
self.view.addSubview(self.sizeToplabel)
self.view.addSubview(self.keepButton)
self.view.addSubview(self.deleteButton)
self.bacView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230)
make.centerX.equalToSuperview()
}
self.animationView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230)
self.topImageView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 19)
make.width.height.equalTo(55)
make.centerX.equalToSuperview()
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalTo(self.animationView.snp.bottom).offset(24)
make.width.equalTo(295)
make.top.equalTo(self.topImageView.snp.bottom).offset(12)
make.width.equalTo(159)
make.height.equalTo(28)
make.centerX.equalToSuperview()
}
self.detailTiplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipLabel.snp.bottom).offset(4)
make.width.equalTo(295)
make.width.equalTo(159)
make.height.equalTo(22)
make.centerX.equalToSuperview()
}
self.infoView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(40)
make.width.equalTo(345)
make.height.equalTo(184)
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(14)
make.width.equalTo(244)
make.height.equalTo(316)
make.centerX.equalToSuperview()
}
self.topImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(24)
make.width.height.equalTo(32)
self.preImageView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(14)
make.width.equalTo(244)
make.height.equalTo(316)
make.centerX.equalToSuperview()
}
self.tipTopLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.width.equalTo(120)
make.top.equalTo(self.preImageView.snp.bottom).offset(32)
make.width.equalTo(333)
make.height.equalTo(22)
make.left.equalTo(self.topImageView.snp.right).offset(8)
}
self.detailTipToplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipTopLabel.snp.bottom).offset(0)
make.width.equalTo(120)
make.height.equalTo(17)
make.left.equalTo(self.topImageView.snp.right).offset(8)
make.centerX.equalToSuperview()
}
self.sizeToplabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(26)
make.left.equalTo(self.detailTipToplabel.snp.right).offset(5)
make.height.equalTo(28)
make.right.equalToSuperview().offset(-20)
}
self.bottomImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(79)
make.width.height.equalTo(32)
}
self.tipBottomLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(75)
make.width.equalTo(120)
make.height.equalTo(22)
make.left.equalTo(self.bottomImageView.snp.right).offset(8)
}
self.detailTipBottomlabel.snp.makeConstraints { make in
make.top.equalTo(self.tipBottomLabel.snp.bottom).offset(0)
make.width.equalTo(120)
make.height.equalTo(17)
make.left.equalTo(self.bottomImageView.snp.right).offset(8)
}
self.sizeBottomlabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(81)
make.left.equalTo(self.detailTipBottomlabel.snp.right).offset(5)
make.top.equalTo(self.tipTopLabel.snp.bottom).offset(4)
make.width.equalTo(333)
make.height.equalTo(28)
make.right.equalToSuperview().offset(-20)
make.centerX.equalToSuperview()
}
self.finalTipLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(34)
make.bottom.equalToSuperview().offset(-20)
self.keepButton.snp.makeConstraints { make in
make.bottom.equalToSuperview().offset(-safeHeight - 78)
make.height.equalTo(51)
make.width.equalTo(304)
make.centerX.equalToSuperview()
}
self.completedButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
make.bottom.equalToSuperview().offset(-24)
self.deleteButton.snp.makeConstraints { make in
make.bottom.equalToSuperview().offset(-safeHeight - 27)
make.height.equalTo(51)
make.width.equalTo(304)
make.centerX.equalToSuperview()
}
}
@objc func completedAction(){
// MARK: 事件方法
@objc func keepButtonAction(){
if currentMediaType == .compressPhoto {
// 将压缩后的照片存到相册
for imageData in self.comDataSource {
if let imageData = self.comDataSource.first {
PHPhotoLibrary.shared().performChanges({
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, data: imageData, options: nil)
......@@ -283,18 +239,17 @@ class CompressCompletedViewController : BaseViewController{
print("保存相片时出错: \(error.localizedDescription)")
}
}
self.jumpToRootVC()
}
}else {
self.jumpToRootVC()
}
}else{
for item in self.comVideoDataSource {
guard let item else {
print("保存视频失败,URL为空")
self.jumpToCompressVC()
return
}
// 保存视频到相册
// 保存视频到相册
if let url = self.comVideoDataSource.first {
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: item as URL)
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url!)
}) { (success, saveError) in
if success {
print("保存视频成功")
......@@ -303,83 +258,50 @@ class CompressCompletedViewController : BaseViewController{
print("保存视频时出错: \(error.localizedDescription)")
}
}
self.jumpToRootVC()
}
}
}
// 删除文件逻辑【系统自动提示是否删除】
var idents :[String] = []
for ele in self.model! {
idents.append(ele.localIdentifier)
}
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: idents, options: nil)
let fileSize = FileTool().calculateTotalAssetSize(fetchResult: fetchResult)
let assetToDelete = fetchResult.firstObject
PHPhotoLibrary.shared().performChanges ({
PHAssetChangeRequest.deleteAssets([assetToDelete] as NSFastEnumeration)
}){ success, error in
var models :[AssetModel] = []
var count = 0
for ele in self.model! {
count = count + 1
self.updateCompressData(flag: ele.localIdentifier)
let deleteModel = AssetModel(localIdentifier: ele.localIdentifier, assetSize: ele.assetSize, createDate: ele.createDate)
models.append(deleteModel)
}
if(success){
// PhotoDataManager.manager.removeDataWhenDeleteInPage(data: models)
PhotoManager.shared.removeDataWhenDeleteInPage(data: models)
print("删除文件成功")
self.showDeleteSuccess(fileCount:count, fileSize: fileSize)
}else {
if let error = error {
print("删除文件时出错: \(error.localizedDescription)")
}
self.showDeleteSuccess(fileCount:count, fileSize: fileSize)
self.jumpToRootVC()
}
}
}
// 删除成功页面
func showDeleteSuccess(fileCount:Int,fileSize:Int64){
DispatchQueue.main.async {
self.jumpToCompressVC()
let vc = DelSuccessViewController()
vc.delType = fileCount > 1 ? "photos" : "photo"
vc.fileSzie = fileSize
vc.fileCount = fileCount
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true)
}
}
func jumpToCompressVC(){
DispatchQueue.main.async {
if let targetVC = self.navigationController?.viewControllers.first(where: { $0 is CompressController }) {
self.navigationController?.popToViewController(targetVC, animated: true)
@objc func deleteButtonAction(){
if let model = self.model {
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [model.localIdentifier], options: nil)
PHPhotoLibrary.shared().performChanges ({
PHAssetChangeRequest.deleteAssets(fetchResult as NSFastEnumeration)
}){ success, error in
if(success){
PhotoManager.shared.removeDataWhenDeleteInPage(data: [self.model!])
print("删除文件成功")
}else {
if let error = error {
print("删除文件时出错: \(error.localizedDescription)")
}
}
self.jumpToRootVC()
}
}else {
self.jumpToRootVC()
}
}
/// 更新数据
/// - Parameter flag: 图片的ident
func updateCompressData(flag : String){
DispatchQueue.main.async {
// 移除VC中的数据
let compressVC = self.navigationController?.viewControllers.first(where: { $0 is CompressController }) as! CompressController as CompressController
compressVC.resourceData.removeAll { $0.localIdentifier == flag }
}
}
// MARK: 辅助方法
override func viewDidLoad() {
super.viewDidLoad()
setUI()
self.animationView.play(fromProgress: 0, toProgress: 1,loopMode: .loop)
/// 返回压缩控制器
func jumpToRootVC(){
DispatchQueue.main.async {
if let viewControllers = self.navigationController?.viewControllers {
for controller in viewControllers.reversed() {
if controller is CompressController {
self.navigationController?.popToViewController(controller, animated: true)
break
}
}
}
}
}
}
......@@ -21,11 +21,7 @@ class CompressController : BaseViewController {
private var compressNav:CompressNavView?
// 排序
var currentSort : ResouceSortType = .largest {
didSet{
clearSelected()
}
}
var currentSort : ResouceSortType = .largest
// 资源类型 - 相册或者视频
var currentResourceType : CompressType = .compressPhoto
......@@ -39,15 +35,12 @@ class CompressController : BaseViewController {
}
}
// 当前页面选中的
var selectedModel : [AssetModel] = []
lazy var collectionView:UICollectionView = {
let layout = WaterfallMutiSectionFlowLayout()
layout.delegate = self
let sview:UICollectionView = UICollectionView.init(frame: CGRect(x: marginLR, y: self.compressNav!.height, width: self.view.width - 2 * marginLR, height: self.view.height - self.compressNav!.height - 102), collectionViewLayout: layout)
let sview:UICollectionView = UICollectionView.init(frame: CGRect(x: marginLR, y: self.compressNav!.height, width: self.view.width - 2 * marginLR, height: self.view.height - self.compressNav!.height), collectionViewLayout: layout)
sview.register(CompressSelectCell.self, forCellWithReuseIdentifier: "CompressSelectCell")
sview.register(CompressCustomHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CompressCustomHeaderView")
sview.register( UICollectionReusableView.self,forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,withReuseIdentifier: "footerID")
......@@ -64,18 +57,6 @@ class CompressController : BaseViewController {
}()
lazy var submitButton : UIButton = {
let view = UIButton()
view.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
view.setTitle("Compress", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.clipsToBounds = true
view.layer.cornerRadius = 23
view.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
view.addTarget(self, action: #selector(startCompress), for: .touchUpInside)
return view
}()
func setUI(){
compressNav = CompressNavView(frame: CGRect(x: 0, y: 0, width: self.view.width, height: statusBarHeight + 44))
......@@ -85,18 +66,7 @@ class CompressController : BaseViewController {
make.top.centerX.width.equalToSuperview()
make.height.equalTo(statusBarHeight + 44)
})
self.view.insertSubview(collectionView, at: 0)
self.view.addSubview(self.submitButton)
self.submitButton.snp.makeConstraints { make in
make.top.equalTo(self.collectionView.snp.bottom).offset(16)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
}
}
override func viewDidLoad() {
......@@ -125,11 +95,6 @@ class CompressController : BaseViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 目的是为了消除cell 的选择按钮状态
if self.selectedModel.count == 0 {
self.collectionView.reloadData()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
......@@ -156,28 +121,6 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
cell.currentMediaType = self.currentResourceType
cell.model = self.resourceData[indexPath.row]
cell.indexPath = indexPath
if self.selectedModel.count == 0 {
cell.choose = false
}
cell.callBack = {[weak self] (model:AssetModel,choose:Bool) ->() in
guard let self else{ return}
// 这里临时管理一个当前选择的资源
if choose == true && !self.selectedModel.contains(model) {
self.selectedModel.append(model)
self.vibrate()
}
if choose == false && self.selectedModel.contains(model){
self.vibrate()
if let index = selectedModel.firstIndex(of: model) {
selectedModel.remove(at: index)
}
}
DispatchQueue.main.async {
// 选择完成后检查选择的是否有值,有值则变换底部的按钮
self.updateSubmitButton()
}
}
return cell
}
......@@ -210,8 +153,7 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.startCompress(model: self.resourceData[indexPath.row])
}
func referenceSizeForHeader(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGSize {
return CGSize (width: self.collectionView.width, height: 188)
......@@ -235,7 +177,6 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
if self.currentResourceType != flag {
self.currentResourceType = flag
// 先移除下,防止点到
self.selectedModel.removeAll()
self.resourceData.removeAll()
// 如果是图片,直接从缓存中加载
if self.currentResourceType == .compressPhoto {
......@@ -289,29 +230,8 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
}
}
func updateSubmitButton(){
if self.selectedModel.count > 0 {
self.submitButton.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
if self.currentResourceType == .compressPhoto {
self.submitButton.setTitle("Compress \(self.selectedModel.count) photos", for: UIControl.State.normal)
}else{
self.submitButton.setTitle("Compress \(self.selectedModel.count) videos", for: UIControl.State.normal)
}
self.submitButton.setTitleColor(.white, for: .normal)
}else{
self.submitButton.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
self.submitButton.setTitle("Compress", for: UIControl.State.normal)
self.submitButton.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
}
}
@objc func startCompress(){
func startCompress(model:AssetModel){
// 如果没有不进行下一步操作
if self.selectedModel.count == 0 {
return
}
if IAPManager.share.isSubscribed == false {
HomePayViewController.show {
if IAPManager.share.isSubscribed == false{
......@@ -326,21 +246,22 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
self.present(alertView, animated: true)
alertView.selectClickCallback = {isSure in
self.view.hideBlur()
alertView.dismiss(animated: true)
if isSure {
self.popAdverTisement()
AdvManager.shared.finisedCallBack = {
self.jumpToNextPage()
alertView.dismiss(animated: true) {
if isSure {
self.popAdverTisement()
AdvManager.shared.finisedCallBack = {
self.jumpToNextPage(model: model)
}
}
}
}
}else {
self.jumpToNextPage()
self.jumpToNextPage(model: model)
}
}
}else {
self.jumpToNextPage()
self.jumpToNextPage(model: model)
}
}
......@@ -349,27 +270,12 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
AdvManager.shared.showInterstitialAd(vc: self)
}
func jumpToNextPage(){
func jumpToNextPage(model:AssetModel){
// 先将值传到下一个页面
let vc : CompressQualityController = CompressQualityController()
vc.currentMediaType = self.currentResourceType
vc.model = self.selectedModel
if self.currentResourceType == .compressPhoto{
vc.detailTiplabel.text = "You've selected \(self.selectedModel.count) photos(A total of \(self.resourceData.count)) to compress."
}else{
vc.detailTiplabel.text = "You've selected \(self.selectedModel.count) videos(A total of \(self.resourceData.count)) to compress."
}
vc.model = model
self.navigationController?.pushViewController(vc, animated: true)
// 然后清理下当前页面的值
clearSelected()
}
func clearSelected() {
self.selectedModel.removeAll()
self.updateSubmitButton()
}
......
......@@ -9,40 +9,21 @@ import Foundation
/// 压缩多少枚举
enum CompressQualityType {
enum CompressQualityType : Double {
// 压缩少量
case low
case low = 0.8
// 压缩中等
case mid
case mid = 0.5
// 压缩较多
case high
case high = 0.2
}
class CompressQualityController : BaseViewController{
var model : [AssetModel]? {
didSet{
if let model = model {
if let modelFirst = model.first {
if self.currentMediaType == .compressPhoto {
let ident = modelFirst.localIdentifier
let image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: ident)
self.imageView.image = image
}else {
// 获取视频的URL
PhotoAndVideoMananger.mananger.getVideoURLFromLocalIdentifier(localIdentifier: modelFirst.localIdentifier) { url, error in
if let url = url {
self.videoView.videoUrl = url
}
}
}
}
}
}
}
var model : AssetModel?
var currentQulityType : Int = 0
var currentQulityType : CompressQualityType = .low
var currentMediaType : CompressType = .compressPhoto {
didSet{
......@@ -59,19 +40,17 @@ class CompressQualityController : BaseViewController{
let view = VideoPlayView()
view.clipsToBounds = true
view.layer.cornerRadius = 12
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.backgroundColor = .clear
return view
}()
lazy var imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 12
imageView.contentMode = .scaleAspectFill
imageView.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
imageView.contentMode = .scaleAspectFit
imageView.backgroundColor = .clear
imageView.image = UIImage(named: "img_compress")
return imageView
}()
......@@ -84,15 +63,6 @@ class CompressQualityController : BaseViewController{
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "You've selected 2 photos(A total of 17) to compress."
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var lowQualityView: QualityView = {
let view = QualityView()
view.type = 0
......@@ -148,7 +118,6 @@ class CompressQualityController : BaseViewController{
self.view.addSubview(self.videoView)
self.view.addSubview(self.imageView)
self.view.addSubview(self.tipLabel)
self.view.addSubview(self.detailTiplabel)
self.view.addSubview(self.lowQualityView)
self.view.addSubview(self.mediumQualityView)
self.view.addSubview(self.highQualityView)
......@@ -159,29 +128,23 @@ class CompressQualityController : BaseViewController{
make.top.equalTo(self.compressNav!.height + 20)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(259)
make.height.equalTo(267 * ((self.view.width - 30) / 345))
}
self.videoView.snp.makeConstraints { make in
make.top.equalTo(self.compressNav!.height + 20)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(259)
make.height.equalTo(267 * ((self.view.width - 30) / 345))
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalTo(self.imageView.snp.bottom).offset(28)
make.top.equalTo(self.imageView.snp.bottom).offset(20)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(22)
}
self.detailTiplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipLabel.snp.bottom).offset(4)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(17)
}
self.lowQualityView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(16)
make.top.equalTo(self.tipLabel.snp.bottom).offset(16)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(61)
......@@ -226,7 +189,7 @@ class CompressQualityController : BaseViewController{
self.lowQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 0
self.currentQulityType = .low
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.lowQualityView.layer.borderWidth = 1
self.mediumQualityView.layer.borderWidth = 0
......@@ -234,12 +197,13 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
setButtonTitleByType(type: .low)
setImageByType(type: .low)
self.vibrate()
}
self.mediumQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 1
self.currentQulityType = .mid
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.lowQualityView.layer.borderWidth = 0
self.mediumQualityView.layer.borderWidth = 1
......@@ -247,12 +211,13 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
setButtonTitleByType(type: .mid)
setImageByType(type: .mid)
self.vibrate()
}
self.highQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 2
self.currentQulityType = .high
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.lowQualityView.layer.borderWidth = 0
self.mediumQualityView.layer.borderWidth = 0
......@@ -260,34 +225,39 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
setButtonTitleByType(type: .high)
setImageByType(type: .high)
self.vibrate()
}
// 设置默认值
setButtonTitleByType(type: .low)
setImageByType(type: .low)
}
func setButtonTitleByType(type : CompressQualityType){
var size : Double = 0.0
if let array = self.model{
for item in array {
size = size + item.assetSize
}
}
// 求和之后看点击的是哪个
var compressSize : Double = 0.0
let size : Double = model?.assetSize ?? 0.0
let compressSize : Double = size * (1 - type.rawValue)
// 设置按钮内容将要压缩的大小
self.submitButton.setTitle("Compress \(formatFileSize(compressSize))", for: .normal)
}
func setImageByType(type : CompressQualityType){
if type == .low {
compressSize = size * 0.2
self.imageView.image = UIImage(named: "img_compress")
self.videoView.videoView.image = UIImage(named: "img_compress 3")
}else if type == .mid {
compressSize = size * 0.5
self.imageView.image = UIImage(named: "img_compress 1")
self.videoView.videoView.image = UIImage(named: "img_compress 4")
}else {
compressSize = size * 0.8
self.imageView.image = UIImage(named: "img_compress 2")
self.videoView.videoView.image = UIImage(named: "img_compress 5")
}
self.submitButton.setTitle("Compress \(formatFileSize(compressSize))", for: .normal)
}
fileprivate func updateNextView(_ compressAllSize: Double, _ compressingView: CompressingView,_ comDataSource : [Data],_ comVideoDataSource : [URL?]) {
DispatchQueue.main.async {
compressingView.removeFromSuperview()
......@@ -296,101 +266,17 @@ class CompressQualityController : BaseViewController{
vc.comDataSource = comDataSource
vc.comVideoDataSource = comVideoDataSource
vc.model = self.model
vc.detailTipToplabel.text = "\(self.model!.count) items"
vc.detailTipBottomlabel.text = "\(self.model!.count) items"
var sum = 0.0
var orgAllSize = 0.0
for modelData in self.model! {
orgAllSize = orgAllSize + modelData.assetSize
}
sum = orgAllSize - compressAllSize
sum = sum / 1000
if sum < 1000{
vc.sizeToplabel.text = String(format:"%.2lfKB",sum)
}else if sum < (1000 * 1000) && sum > 1000{
sum = sum / 1000
vc.sizeToplabel.text = String(format:"%.2lfMB",sum)
}else{
sum = sum / (1000 * 1000)
vc.sizeToplabel.text = String(format:"%.2lfGB",sum)
}
let str = String(format:"%.2lf",(orgAllSize - compressAllSize) / orgAllSize)
vc.sizeBottomlabel.text = "\(str)%"
self.navigationController?.pushViewController(vc, animated: true)
}
}
@objc func submitAction(){
let actionBlock = { [weak self] in
guard let self = self else { return }
let compressingView : CompressingView = CompressingView(frame: self.view.bounds)
compressingView.data = self.model
self.view.addSubview(compressingView)
// 开始压缩
let manager : CompressViewModel = CompressViewModel()
var currentQulity = 0.2
if currentQulityType == 1 {
currentQulity = 0.5
}
if currentQulityType == 2 {
currentQulity = 0.8
}
var comDataSource : [Data] = []
if self.currentMediaType == .compressPhoto {
// 表示压缩图片
manager.compress(assets: self.model!, compressionQuality: currentQulity) {progress in
compressingView.animationView.setProgress(CGFloat(progress), animated: false, duration: 0.1)
} completion: { compressedDataArray, errorArray in
var compressAllSize = 0.0
for (index, data) in compressedDataArray.enumerated() {
if let error = errorArray[index] {
print("第 \(index + 1) 个文件压缩出错: \(error.localizedDescription)")
} else if let data = data {
print("第 \(index + 1) 个文件压缩完成,压缩后大小: \(data.count) 字节")
compressAllSize = compressAllSize + Double(data.count)
comDataSource.append(data)
} else {
print("第 \(index + 1) 个文件压缩失败")
}
}
self.updateNextView(compressAllSize,compressingView,comDataSource,[])
}
}else{
// 压缩视频
var compressAllSize : Double = 0.0
CompressViewModel.compressVideos(models: self.model!, quality: Float(currentQulity)) { progress in
compressingView.animationView.setProgress(CGFloat(progress), animated: false, duration: 0.1)
} completion: { (outputURLs, errors) in
for (index, outputURL) in outputURLs.enumerated() {
if let outputURL = outputURL {
do {
let attributes = try FileManager.default.attributesOfItem(atPath: outputURL.path)
if let fileSize = attributes[.size] as? Int64 {
compressAllSize = compressAllSize + Double(fileSize)
}
} catch {
Print("获取视频文件大小失败")
}
} else if let error = errors[index] {
print("Error compressing video \(index): \(error.localizedDescription)")
}
}
Print("---------压缩后的大小:\(compressAllSize)")
// 不管成功失败都跳转下一页
self.updateNextView(compressAllSize,compressingView,[],outputURLs)
}
}
}
actionBlock()
// 跳转进度页面
let vc : CompressingViewController = CompressingViewController()
vc.model = self.model
vc.qualityType = self.currentQulityType
vc.currentMediaType = self.currentMediaType
self.navigationController?.pushViewController(vc, animated: true)
}
}
//
// CompressingViewController.swift
// PhoneManager
//
// Created by edy on 2025/5/21.
//
import UIKit
import Lottie
class CompressingViewController: BaseViewController {
var currentMediaType : CompressType = .compressPhoto
var model : AssetModel? {
didSet{
if let model = model {
DispatchQueue.main.async {
self.orgSizeLabel.text = formatFileSize(model.assetSize)
}
}
}
}
var qualityType : CompressQualityType? {
didSet{
if let model = model {
if let qualityType = qualityType {
DispatchQueue.main.async {
self.targetSizeLabel.text = formatFileSize(model.assetSize * qualityType.rawValue)
}
}
}
}
}
lazy var bacImageView : UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "Group_1171275114")
return view
}()
lazy var animationViewBacView : UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "* 白色实心圆-小")
view.backgroundColor = .clear
return view
}()
lazy var animationView : LottieAnimationView = {
let animationView = LottieAnimationView(name: "iOS压缩完成")
animationView.layer.cornerRadius = 12
animationView.backgroundColor = .clear
animationView.loopMode = .loop
return animationView
}()
lazy var tipLabel : UILabel = {
let label = UILabel()
label.text = "We're freeing up space on your device!"
label.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
label.font = UIFont.systemFont(ofSize: 18, weight: .medium)
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
lazy var orgSizeLabel : UILabel = {
let label = UILabel()
label.textColor = UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .medium)
label.textAlignment = .left
return label
}()
lazy var targetSizeLabel : UILabel = {
let label = UILabel()
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .medium)
label.textAlignment = .right
return label
}()
lazy var progressBar : CustomCompressProgressBar = {
let bar = CustomCompressProgressBar()
bar.thumbImage = UIImage(systemName: "arrowtriangle.right.fill")?.withTintColor(.red)
bar.layer.cornerRadius = 3.5
bar.clipsToBounds = true
return bar
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.titleView.isHidden = true
setUI()
startCompress()
}
// MARK:设置数据
func startCompress(){
if let qualityType = qualityType {
let manager : CompressViewModel = CompressViewModel()
if self.currentMediaType == .compressPhoto {
// 表示压缩图片
var comDataSource : [Data] = []
manager.compress(assets: [self.model!], compressionQuality: qualityType.rawValue) {progress in
Print(progress)
DispatchQueue.main.async {
self.progressBar.updateProgress(to: CGFloat(progress))
}
} completion: { compressedDataArray, errorArray in
var compressAllSize = 0.0
for (index, data) in compressedDataArray.enumerated() {
if let error = errorArray[index] {
print("第 \(index + 1) 个文件压缩出错: \(error.localizedDescription)")
} else if let data = data {
print("第 \(index + 1) 个文件压缩完成,压缩后大小: \(data.count) 字节")
compressAllSize = compressAllSize + Double(data.count)
comDataSource.append(data)
} else {
print("第 \(index + 1) 个文件压缩失败")
}
}
self.updateNextView(compressAllSize,comDataSource,[])
}
}else{
// 压缩视频
var compressAllSize : Double = 0.0
CompressViewModel.compressVideos(models: [self.model!], quality: Float(qualityType.rawValue)) { progress in
DispatchQueue.main.async {
self.progressBar.updateProgress(to: CGFloat(progress))
}
} completion: { (outputURLs, errors) in
for (index, outputURL) in outputURLs.enumerated() {
if let outputURL = outputURL {
do {
let attributes = try FileManager.default.attributesOfItem(atPath: outputURL.path)
if let fileSize = attributes[.size] as? Int64 {
compressAllSize = compressAllSize + Double(fileSize)
}
} catch {
Print("获取视频文件大小失败")
}
} else if let error = errors[index] {
print("Error compressing video \(index): \(error.localizedDescription)")
}
}
Print("---------压缩后的大小:\(compressAllSize)")
// 不管成功失败都跳转下一页
self.updateNextView(compressAllSize,[],outputURLs)
}
}
}
}
fileprivate func updateNextView(_ compressAllSize: Double,_ comDataSource : [Data],_ comVideoDataSource : [URL?]) {
DispatchQueue.main.async {
let vc = CompressCompletedViewController()
vc.currentMediaType = self.currentMediaType
vc.comDataSource = comDataSource
vc.comVideoDataSource = comVideoDataSource
vc.model = self.model
vc.completedSize = compressAllSize
self.navigationController?.pushViewController(vc, animated: true)
}
}
// MARK:设置UI
func setUI(){
self.view.addSubview(self.bacImageView)
self.bacImageView.snp.makeConstraints { make in
make.height.equalTo(211)
make.width.equalTo(264.7)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(96 + statusBarHeight)
}
self.view.addSubview(self.animationViewBacView)
self.animationViewBacView.snp.makeConstraints { make in
make.top.equalTo(self.bacImageView.snp.top).offset(58)
make.width.height.equalTo(108.75)
make.centerX.equalToSuperview()
}
self.view.addSubview(self.animationView)
self.animationView.snp.makeConstraints { make in
make.width.height.equalTo(145)
make.top.equalTo(self.bacImageView.snp.top).offset(40)
make.centerX.equalToSuperview()
}
self.view.addSubview(self.tipLabel)
self.tipLabel.snp.makeConstraints { make in
make.width.equalTo(304)
make.height.equalTo(50)
make.centerX.equalToSuperview()
make.top.equalTo(self.bacImageView.snp.bottom).offset(96)
}
self.view.addSubview(self.orgSizeLabel)
self.orgSizeLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.height.equalTo(22)
make.bottom.equalTo(-66 - safeHeight)
}
self.view.addSubview(self.targetSizeLabel)
self.targetSizeLabel.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-16)
make.height.equalTo(22)
make.bottom.equalTo(-66 - safeHeight)
}
self.view.addSubview(self.progressBar)
self.progressBar.snp.makeConstraints { make in
make.left.equalTo(16)
make.right.equalToSuperview().offset(-16)
make.height.equalTo(7)
make.bottom.equalTo(-43 - safeHeight)
}
self.animationView.play(fromProgress: 0, toProgress: 1 , loopMode: .loop)
}
}
......@@ -10,7 +10,7 @@ import Foundation
class CompressingView: UIView{
var data: [AssetModel]?
var data: AssetModel?
override init(frame: CGRect) {
super.init(frame: frame)
......
//
// CustomProgressBar.swift
// PhoneManager
//
// Created by edy on 2025/5/21.
//
import UIKit
class CustomCompressProgressBar: UIView {
// 前景色(已完成进度颜色)
private let foregroundLayer = CALayer()
// 进度指示图标
private let thumbLayer = CALayer()
// 当前进度值(0-1)
private var progress: CGFloat = 0.0
// 最后一次更新时间
private var lastUpdateTime: Date?
// 缩略图图片
var thumbImage: UIImage? {
didSet {
thumbLayer.contents = thumbImage?.cgImage
thumbLayer.frame = CGRect(origin: .zero, size: thumbImage?.size ?? CGSize(width: 20, height: 20))
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
backgroundColor = .white
layer.cornerRadius = frame.height / 2
layer.masksToBounds = true
// 设置前景层
foregroundLayer.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
foregroundLayer.cornerRadius = layer.cornerRadius
layer.addSublayer(foregroundLayer)
// 设置缩略图层
thumbLayer.contentsGravity = .resizeAspect
layer.addSublayer(thumbLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
updateLayers(for: progress)
}
func updateProgress(to newProgress: CGFloat) {
let currentTime = Date()
let clampedProgress = max(0, min(newProgress, 1.0))
var duration: TimeInterval = 0
if let lastTime = lastUpdateTime {
let timeSinceLast = currentTime.timeIntervalSince(lastTime)
duration = timeSinceLast < 1.0 ? 1.0 : timeSinceLast
}
animateProgress(from: progress, to: clampedProgress, duration: duration)
lastUpdateTime = currentTime
}
private func updateLayers(for progress: CGFloat) {
let foregroundWidth = bounds.width * progress
foregroundLayer.frame = CGRect(x: 0, y: 0, width: foregroundWidth, height: bounds.height)
let thumbSize = thumbLayer.bounds.size
let thumbX = progress * bounds.width - thumbSize.width/2
thumbLayer.frame.origin = CGPoint(
x: max(0, min(thumbX, bounds.width - thumbSize.width)),
y: (bounds.height - thumbSize.height)/2
)
}
private func animateProgress(from oldProgress: CGFloat, to newProgress: CGFloat, duration: TimeInterval) {
foregroundLayer.removeAllAnimations()
thumbLayer.removeAllAnimations()
guard duration > 0 else {
progress = newProgress
updateLayers(for: newProgress)
return
}
let foregroundAnimation = CABasicAnimation(keyPath: "bounds.size.width")
foregroundAnimation.fromValue = oldProgress * bounds.width
foregroundAnimation.toValue = newProgress * bounds.width
foregroundAnimation.duration = duration
foregroundAnimation.timingFunction = CAMediaTimingFunction(name: .linear)
let thumbAnimation = CABasicAnimation(keyPath: "position.x")
thumbAnimation.fromValue = (oldProgress * bounds.width) - thumbLayer.bounds.width/2
thumbAnimation.toValue = (newProgress * bounds.width) - thumbLayer.bounds.width/2
thumbAnimation.duration = duration
thumbAnimation.timingFunction = CAMediaTimingFunction(name: .linear)
progress = newProgress
CATransaction.begin()
CATransaction.setDisableActions(true)
foregroundLayer.bounds.size.width = newProgress * bounds.width
thumbLayer.position.x = (newProgress * bounds.width) - thumbLayer.bounds.width/2
CATransaction.commit()
foregroundLayer.add(foregroundAnimation, forKey: nil)
thumbLayer.add(thumbAnimation, forKey: nil)
}
}
......@@ -9,15 +9,6 @@ import UIKit
class VideoPlayView: UIView {
var videoUrl : URL? {
didSet {
if let url = videoUrl {
self.videoView.playVideo(from: url)
self.videoView.pause()
}
}
}
lazy var playImageView : UIImageView = {
let imageView = UIImageView()
imageView.backgroundColor = .clear
......@@ -28,18 +19,19 @@ class VideoPlayView: UIView {
lazy var timeLabel : UILabel = {
let label = UILabel()
label.textColor = .white
label.text = "00:00"
label.text = "00:25"
label.font = UIFont.systemFont(ofSize: 14, weight: .semibold)
label.textAlignment = .right
return label
}()
lazy var videoView : SecretVideoPlayer = {
let view = SecretVideoPlayer()
lazy var videoView : UIImageView = {
let view = UIImageView()
view.clipsToBounds = true
view.layer.cornerRadius = 12
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.contentMode = .scaleAspectFit
view.backgroundColor = .clear
return view
}()
......@@ -57,25 +49,6 @@ class VideoPlayView: UIView {
make.top.equalToSuperview().offset(8)
make.height.equalTo(20)
}
self.videoView.callBackCurrtntTimeString = {[weak self]text in
guard let self else {return}
DispatchQueue.main.async {
self.timeLabel.text = text
}
}
self.videoView.tapPauseCallback = {[weak self] state in
guard let self else {return}
if state == .playing {
self.playImageView.isHidden = true
}
if state == .pause {
self.playImageView.isHidden = false
}
if state == .end {
self.playImageView.isHidden = false
self.timeLabel.text = "00:00"
}
}
self.addSubview(self.playImageView)
......
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