Commit 3b072eda authored by CZ1004's avatar CZ1004

合并

parents 7f7333dc fe59c4f0
......@@ -251,6 +251,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
31462A82044E900B1963FE3A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PhoneManager/Pods-PhoneManager-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PhoneManager/Pods-PhoneManager-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PhoneManager/Pods-PhoneManager-resources.sh\"\n";
showEnvVarsInLog = 0;
};
594FD43819933850E07C4C9C /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
......
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_cmpress_home_nor.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_cmpress_home_nor@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_cmpress_home_nor@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_compressed_end.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_compressed_end@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_compressed_end@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_freed_end.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_freed_end@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_freed_end@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_newest_similar.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_newest_similar@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_newest_similar@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_sel_com.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_sel_com@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_sel_com@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_unsel_com.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_unsel_com@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_unsel_com@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "icon_left_setting_grey.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon_left_setting_grey@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icon_left_setting_grey@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "button_switch_off.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "button_switch_off@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "button_switch_off@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "button_switch_on.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "button_switch_on@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "button_switch_on@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_about_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_about_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_about_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_delete_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_delete_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_delete_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_email_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_email_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_email_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_faq_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_faq_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_faq_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_hints_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_hints_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_hints_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_ins_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_ins_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_ins_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_list_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_list_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_list_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_more_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_more_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_more_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_out_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_out_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_out_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_pin_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_pin_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_pin_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_privacy_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_privacy_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_privacy_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_rate_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_rate_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_rate_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_restore_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_restore_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_restore_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_share_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_share_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_share_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_vibration_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_vibration_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_vibration_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "ic_widgets_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_widgets_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_widgets_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "icon_left_setting_grey.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon_left_setting_grey@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "icon_left_setting_grey@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_light_setting.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_light_setting@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_light_setting@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_return_pop.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_return_pop@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_return_pop@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "logo_phone_manager.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "logo_phone_manager@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "logo_phone_manager@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
//
// CompressSelectCell.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
typealias CompressSelectCellCallback = (ResourceModel,Bool)->Void
class CompressSelectCell : UICollectionViewCell {
var callBack : CompressSelectCellCallback = {model,choose in}
var model : ResourceModel? {
didSet{
guard let model = self.model else {return}
let image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: model.ident)
self.backImageView.image = image
// 把压缩前的值减去压缩后的值就为可以节省的值。然后这里需要判定下如果是大于1000MB,则再除以1024换算成GB
let saveSize = model.orgSize - model.compressSize
if saveSize > 1000 {
self.saveSizeLabel.text = String(format: "Save %.2f GB" ,saveSize/1024.0)
}else{
self.saveSizeLabel.text = String(format: "Save %.2f MB" ,saveSize)
}
}
}
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()
view.isUserInteractionEnabled = true
view.contentMode = .scaleAspectFill
view.clipsToBounds = true
view.layer.masksToBounds = true
view.layer.cornerRadius = 12
return view
}()
lazy var saveSizeView: UIView = {
let view = UIView()
view.layer.masksToBounds = true
view.layer.cornerRadius = 4
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
return view
}()
lazy var saveSizeLabel: UILabel = {
let view = UILabel()
view.textAlignment = .left
view.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
view.font = UIFont.systemFont(ofSize: 12, weight: .regular)
view.text = "Save 1.3MB"
return view
}()
lazy var moreImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "icon_left_setting_grey")
view.backgroundColor = .clear
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(){
self.choose = !self.choose
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(self.backImageView)
self.addSubview(self.saveSizeView)
self.saveSizeView.addSubview(self.saveSizeLabel)
self.saveSizeView.addSubview(self.moreImageView)
self.addSubview(self.selectImageView)
self.backImageView.snp.makeConstraints { make in
make.left.right.height.width.equalToSuperview()
}
self.saveSizeView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.bottom.equalToSuperview().offset(-12)
make.height.equalTo(48)
make.width.equalTo(120)
}
self.saveSizeLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(8)
make.centerY.equalToSuperview()
make.height.equalTo(48)
make.width.equalTo(120)
}
self.moreImageView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-4)
make.centerY.equalToSuperview()
make.height.width.equalTo(16)
}
self.selectImageView.snp.makeConstraints { make in
make.bottom.right.equalToSuperview().offset(-12)
make.height.width.equalTo(24)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// CompressSortCell.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import Foundation
class CompressSortCell : UITableViewCell {
var cellTag : Int = 0
var callBack : callBack<Any> = {cellTag in}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
self.contentView.addSubview(self.selectButton)
self.selectButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(0)
make.right.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(6)
make.bottom.equalToSuperview().offset(-6)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var selectButton : UIButton = {
let view = UIButton(type: UIButton.ButtonType.custom)
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.layer.cornerRadius = 12
view.clipsToBounds = true
view.setTitleColor(UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1), for: .normal)
view.addTarget(self, action: #selector(selectAction), for: .touchUpInside)
view.layer.borderColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
return view
}()
@objc func selectAction(){
callBack(self.cellTag)
}
}
//
// CompressCompletedViewController.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class CompressCompletedViewController : BaseViewController{
var model : [ResourceModel]?
lazy var imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 12
imageView.backgroundColor = .gray
return imageView
}()
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.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.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var infoView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.clipsToBounds = true
view.layer.cornerRadius = 12
return view
}()
lazy var topImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_compressed_end")
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 = {
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 sizeToplabel: UILabel = {
let label = UILabel()
label.text = "511MB"
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.textAlignment = .center
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 bottomImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_freed_end")
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 = .center
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 = {
let view = UIButton()
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, green: 0.51, blue: 1, alpha: 1)
view.addTarget(self, action: #selector(completedAction), for: .touchUpInside)
return view
}()
func setUI(){
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.titleView.isHidden = true
self.view.addSubview(self.imageView)
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.imageView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230)
make.centerX.equalToSuperview()
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalTo(self.imageView.snp.bottom).offset(24)
make.width.equalTo(295)
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.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.centerX.equalToSuperview()
}
self.topImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(24)
make.width.height.equalTo(32)
}
self.tipTopLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.width.equalTo(198)
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(198)
make.height.equalTo(17)
make.left.equalTo(self.topImageView.snp.right).offset(8)
}
self.sizeToplabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(26)
make.width.equalTo(64)
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(198)
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(198)
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.width.equalTo(64)
make.height.equalTo(28)
make.right.equalToSuperview().offset(-20)
}
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.completedButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
make.bottom.equalToSuperview().offset(-24)
}
}
@objc func completedAction(){
// 提示是否删除照片
let compressTipView : CompressTipView = CompressTipView(frame: self.view.bounds)
self.view.addSubview(compressTipView)
compressTipView.callBack = {[weak self] allow in
guard let self else {return}
if let targetVC = self.navigationController?.viewControllers.first(where: { $0 is CompressController }) {
self.navigationController?.popToViewController(targetVC, animated: true)
}
// 如果不允许就两张都放进去,否则异步删除照片
if allow as! Bool == false {
// 删除照片逻辑
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
setUI()
}
}
//
// CompressController.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
import SnapKit
import Photos
class CompressController : BaseViewController {
private var compressNav:CompressNavView?
// 排序
var currentSort : Int = 0 {
didSet{
clearSelected()
}
}
// 资源类型 - 相册或者视频
var currentResourceType : Int = 0
// 所有的数据
var resourceData = [ResourceModel](){
didSet{
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
// 当前页面选中的
var selectedModel : [ResourceModel] = []
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)
sview.register(CompressSelectCell.self, forCellWithReuseIdentifier: "CompressSelectCell")
sview.register(CompressCustomHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CompressCustomHeaderView")
sview.register( UICollectionReusableView.self,forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,withReuseIdentifier: "footerID")
sview.dataSource = self
sview.delegate = self
sview.showsVerticalScrollIndicator = false
if #available(iOS 11.0, *) {
sview.contentInsetAdjustmentBehavior = .never
}
sview.backgroundColor = .clear
return sview
}()
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))
self.view.addSubview(compressNav!)
compressNav?.snp.makeConstraints({ make in
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() {
super.viewDidLoad()
view.backgroundColor = .white
self.navigationController?.navigationBar.isHidden = true
setUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 这里默认去请求下当前的数据资源
let viewModel = CompressViewModel()
viewModel.getAllPhotos {[weak self] models in
guard let self else {return}
self.resourceData = models
}
}
}
extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.resourceData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CompressSelectCell", for: indexPath) as! CompressSelectCell
cell.model = self.resourceData[indexPath.row]
if self.selectedModel.count == 0 {
cell.choose = false
}
cell.callBack = {[weak self] (model:ResourceModel,choose:Bool) ->() in
guard let self else{ return}
// 这里临时管理一个当前选择的资源
if choose == true && !self.selectedModel.contains(model) {
self.selectedModel.append(model)
}
if choose == false && self.selectedModel.contains(model){
if let index = selectedModel.firstIndex(of: model) {
selectedModel.remove(at: index)
}
}
DispatchQueue.main.async {
// 选择完成后检查选择的是否有值,有值则变换底部的按钮
self.updateSubmitButton()
}
}
return cell
}
func heightForRowAtIndexPath(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, indexPath: IndexPath, itemWidth: CGFloat) -> CGFloat {
if indexPath.row % 2 == 0{
return itemWidth
}
return itemWidth + 67
}
func columnNumber(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> Int {
return 2
}
func lineSpacing(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGFloat {
return 8
}
func interitemSpacing(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGFloat {
return 11
}
func spacingWithLastSection(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGFloat {
return 8
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
func referenceSizeForHeader(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGSize {
return CGSize (width: self.collectionView.width, height: 188)
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionHeader {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "CompressCustomHeaderView", for: indexPath) as! CompressCustomHeaderView
header.callBack = {[weak self] text in
guard let self else {return}
let sortView = CompressSortView(frame: self.view.bounds)
// 这两行是为了进入页面的时候选中
sortView.currentIndex = self.currentSort
sortView.tableView.reloadData()
self.view.addSubview(sortView)
sortView.callBack = {[weak self] sortType in
guard let self else {return}
self.currentSort = sortType as! Int
self.sortByType(sortType: self.currentSort, header: header)
}
}
header.modeData = self.resourceData
return header
}else{
let footer = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
withReuseIdentifier: "footerID",
for: indexPath
)
return footer
}
}
func sortByType(sortType:Int,header:CompressCustomHeaderView){
let viewModel = CompressViewModel()
switch sortType {
case 0:
header.selectlabel.text = "Largest"
// 按照文件大小降序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 1, sortKind: 0)
break
case 1:
header.selectlabel.text = "Smallest"
// 按照文件大小升序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 0, sortKind: 0)
break
case 2:
header.selectlabel.text = "Newest"
// 按照时间降序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 1, sortKind: 1)
break
case 3:
header.selectlabel.text = "Oldest"
// 按照时间升序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 0, sortKind: 1)
break
default:
break
}
}
func updateSubmitButton(){
if self.selectedModel.count > 0 {
self.submitButton.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
if self.currentResourceType == 0 {
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(){
// 如果没有不进行下一步操作
if self.selectedModel.count == 0 {
return
}
// 先将值传到下一个页面
let vc : CompressQualityController = CompressQualityController()
vc.model = self.selectedModel
vc.detailTiplabel.text = "You've selected \(self.selectedModel.count) out of \(self.resourceData.count) photos to compress."
self.navigationController?.pushViewController(vc, animated: true)
// 然后清理下当前页面的值
clearSelected()
}
func clearSelected() {
self.selectedModel.removeAll()
self.updateSubmitButton()
}
}
//
// CompressQualityController.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class CompressQualityController : BaseViewController{
var model : [ResourceModel]? {
didSet{
let ident = model!.first!.ident
let image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: ident)
self.imageView.image = image
}
}
var currentQulityType : Int = 0
private var compressNav:CompressNavView?
lazy var imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 12
imageView.backgroundColor = .clear
return imageView
}()
lazy var tipLabel: UILabel = {
let label = UILabel()
label.text = "Select photo quality after compression"
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "You've selected 2 out of 253 photos 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
view.selectedImageView.image = UIImage(named: "ic_unsel_com")
return view
}()
lazy var mediumQualityView: QualityView = {
let view = QualityView()
view.type = 1
view.tipLabel.text = "Medium quality"
view.detailTiplabel.text = "Compress up to 50% of the size"
return view
}()
lazy var highQualityView: QualityView = {
let view = QualityView()
view.type = 2
view.tipLabel.text = "High quality"
view.detailTiplabel.text = "Compress up to 20% of the size"
return view
}()
lazy var submitButton : 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.clipsToBounds = true
view.layer.cornerRadius = 23
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
view.addTarget(self, action: #selector(submitAction), for: .touchUpInside)
return view
}()
func setUI(){
compressNav = CompressNavView(frame: CGRect(x: 0, y: 0, width: self.view.width, height: statusBarHeight + 44))
self.view.addSubview(compressNav!)
compressNav?.snp.makeConstraints({ make in
make.top.centerX.width.equalToSuperview()
make.height.equalTo(statusBarHeight + 44)
})
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)
self.view.addSubview(self.submitButton)
self.imageView.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)
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalTo(self.imageView.snp.bottom).offset(28)
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.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(61)
}
self.mediumQualityView.snp.makeConstraints { make in
make.top.equalTo(self.lowQualityView.snp.bottom).offset(12)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(61)
}
self.highQualityView.snp.makeConstraints { make in
make.top.equalTo(self.mediumQualityView.snp.bottom).offset(12)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(61)
}
self.submitButton.snp.makeConstraints { make in
make.bottom.equalTo(-40)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.navigationController?.navigationBar.isHidden = true
setUI()
self.lowQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 0
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
}
self.mediumQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 1
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
}
self.highQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 2
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
}
}
@objc func submitAction(){
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
}
manager.compress(assets: self.model!, compressionQuality: currentQulity) {progress in
compressingView.animationView.setProgress(CGFloat(progress), animated: true, duration: 0.1)
} completion: { compressedDataArray, errorArray in
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) 字节")
} else {
print("第 \(index + 1) 张图片压缩失败")
}
}
DispatchQueue.main.asyncAfter(deadline:.now() + 2) {
compressingView.removeFromSuperview()
let vc = CompressCompletedViewController()
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
var compressAllSize = 0.0
for modelData in self.model! {
orgAllSize = orgAllSize + modelData.orgSize
compressAllSize = compressAllSize + modelData.compressSize
sum = sum + modelData.orgSize - modelData.compressSize
}
if sum > 1000 {
sum = sum / 1024
vc.sizeToplabel.text = "\(sum)GB"
}else{
vc.sizeToplabel.text = "\(sum)MB"
}
let str = String(format:"%.2lf",(orgAllSize - compressAllSize) / orgAllSize)
vc.sizeBottomlabel.text = "\(str)%"
self.navigationController?.pushViewController(vc, animated: true)
}
}
// DispatchQueue.main.async {
// compressingView.removeFromSuperview()
// let vc = CompressCompletedViewController()
// 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
// var compressAllSize = 0.0
// for modelData in self.model! {
// orgAllSize = orgAllSize + modelData.orgSize
// compressAllSize = compressAllSize + modelData.compressSize
// sum = sum + modelData.orgSize - modelData.compressSize
// }
// if sum > 1000 {
// sum = sum / 1024
// vc.sizeToplabel.text = "\(sum)GB"
// }else{
// vc.sizeToplabel.text = "\(sum)MB"
// }
// let str = String(format:"%.2lf",(orgAllSize - compressAllSize) / orgAllSize)
// vc.sizeBottomlabel.text = "\(str)%"
//
//
// self.navigationController?.pushViewController(vc, animated: true)
// }
}
}
//
// ResourceModel.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
import Photos
struct ResourceModel : Equatable{
var ident : String
var compressSize : Double
var orgSize: Double
var createDate : Date
var imageAsset: PHAsset
init(ident: String, compressSize: Double, orgSize: Double, createDate: Date, imageAsset: PHAsset) {
self.ident = ident
self.compressSize = compressSize
self.orgSize = orgSize
self.createDate = createDate
self.imageAsset = imageAsset
}
}
//
// CircularProgressBar.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import Foundation
class CircularProgressBar: UIView {
private var progressLayer = CAShapeLayer()
private var trackLayer = CAShapeLayer()
var textLabel : UILabel = {
let view = UILabel()
view.text = "Compressing..."
view.textColor = .white
view.font = UIFont.systemFont(ofSize: 16, weight: .bold)
return view
}()
var progressColor = UIColor.blue {
didSet {
progressLayer.strokeColor = progressColor.cgColor
}
}
var trackColor = UIColor.lightGray {
didSet {
trackLayer.strokeColor = trackColor.cgColor
}
}
var lineWidth: CGFloat = 10 {
didSet {
progressLayer.lineWidth = lineWidth
trackLayer.lineWidth = lineWidth
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
self.addSubview(self.textLabel)
self.textLabel.snp.makeConstraints { make in
make.width.equalTo(113 * RScreenW())
make.height.equalTo(22)
make.center.equalToSuperview()
}
// 创建轨道图层
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.strokeColor = trackColor.cgColor
trackLayer.lineWidth = lineWidth
layer.addSublayer(trackLayer)
// 创建进度图层
progressLayer.fillColor = UIColor.clear.cgColor
progressLayer.strokeColor = progressColor.cgColor
progressLayer.lineWidth = lineWidth
progressLayer.strokeEnd = 0
progressLayer.lineCap = .round
layer.addSublayer(progressLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = (min(bounds.width, bounds.height) - lineWidth) / 2
let circularPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: -.pi / 2, endAngle: 1.5 * .pi, clockwise: true)
trackLayer.path = circularPath.cgPath
progressLayer.path = circularPath.cgPath
}
func setProgress(_ progress: CGFloat, animated: Bool = true, duration: TimeInterval = 1.0) {
if animated {
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.toValue = progress
animation.duration = duration
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
progressLayer.add(animation, forKey: "progressAnimation")
} else {
progressLayer.strokeEnd = progress
}
}
}
//
// CompressCustomHeaderView.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class CompressCustomHeaderView: UICollectionReusableView{
var callBack: callBack<Any> = {text in }
var modeData = [ResourceModel]() {
didSet{
// 计算图片总大小
var sum = 0.0
// 计算可节省大小
var saveSum = 0.0
for model in self.modeData{
sum = sum + model.orgSize
saveSum = saveSum + (model.orgSize - model.compressSize)
}
if sum > 1000 {
self.siezLabel.text = String(format: "%.2f GB" ,(sum/1024))
}else{
self.siezLabel.text = String(format: "%.2f MB" ,(sum))
}
if saveSum > 1000 {
self.saveSizeLabel.text = String(format: "%.2f GB" ,(saveSum/1024.0))
}else {
self.saveSizeLabel.text = String(format: "%.2f MB" ,(saveSum))
}
}
}
lazy var titlelabel :UILabel = {
let label = UILabel()
label.text = "Compress"
label.textAlignment = .left
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 20, weight: .bold)
return label
}()
lazy var btnView :UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.layer.cornerRadius = 16
view.clipsToBounds = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(selectQulity))
view.isUserInteractionEnabled = true
view.addGestureRecognizer(tap)
return view
}()
lazy var selectImageView :UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_newest_similar")
return view
}()
lazy var selectlabel :UILabel = {
let label = UILabel()
label.text = "Largest"
label.textAlignment = .center
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
return label
}()
lazy var siezLabel :UILabel = {
let label = UILabel()
label.text = "1.02 GB"
label.textAlignment = .left
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .regular)
return label
}()
lazy var changeView :CompressSwitchView = {
let view = CompressSwitchView()
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.layer.cornerRadius = 8
view.clipsToBounds = true
return view
}()
lazy var tipView :UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_cmpress_home_nor")
return view
}()
lazy var tipLabel :UILabel = {
let label = UILabel()
label.text = "Compress your media files and save up to"
label.textAlignment = .left
label.numberOfLines = 0
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
return label
}()
lazy var saveSizeLabel :UILabel = {
let label = UILabel()
label.text = "511MB"
label.textAlignment = .right
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
return label
}()
private func setUI(){
self.addSubview(self.titlelabel)
self.addSubview(self.btnView)
self.btnView.addSubview(self.selectImageView)
self.btnView.addSubview(self.selectlabel)
self.addSubview(self.siezLabel)
self.addSubview(self.changeView)
self.addSubview(self.tipView)
self.addSubview(self.tipLabel)
self.addSubview(self.saveSizeLabel)
self.titlelabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(14)
make.width.equalTo(96 * RScreenW())
make.height.equalTo(28)
}
self.btnView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(12)
make.width.equalTo(103 * RScreenW())
make.height.equalTo(32)
}
self.selectImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.centerY.equalToSuperview()
make.width.height.equalTo(20)
}
self.selectlabel.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-12)
make.top.equalToSuperview().offset(6)
make.width.equalTo(51 * RScreenW())
make.height.equalTo(20)
}
self.siezLabel.snp.makeConstraints { make in
make.left.equalTo(0)
make.right.equalTo(0)
make.top.equalTo(self.btnView.snp.bottom).offset(8)
make.height.equalTo(20)
}
self.changeView.snp.makeConstraints { make in
make.left.equalTo(0)
make.right.equalTo(0)
make.top.equalTo(self.siezLabel.snp.bottom).offset(12)
make.height.equalTo(46)
}
self.tipView.snp.makeConstraints { make in
make.left.equalTo(0)
make.top.equalTo(self.changeView.snp.bottom).offset(15)
make.width.height.equalTo(28)
}
self.tipLabel.snp.makeConstraints { make in
make.left.equalTo(self.tipView.snp.right).offset(4)
make.width.equalTo(206 * RScreenW())
make.height.equalTo(34)
make.centerY.equalTo(self.tipView.snp.centerY)
}
self.saveSizeLabel.snp.makeConstraints { make in
make.left.equalTo(self.tipLabel.snp.right).offset(4)
make.right.equalTo(0)
make.height.equalTo(22)
make.centerY.equalTo(self.tipView.snp.centerY)
}
}
@objc func selectQulity(){
callBack("selectedQulity")
}
override init(frame: CGRect) {
super.init(frame: frame)
setUI()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUI()
}
}
//
// CompressNavView.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class CompressNavView : UIView {
private var backButton:UIButton!
private var proBtn:UIButton!
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
backButton = UIButton()
backButton.setImage(UIImage(named: "nav_back"), for: .normal)
backButton.addTarget(self, action: #selector(backBtnClick), for: .touchUpInside)
self.addSubview(backButton)
backButton.snp.makeConstraints { make in
make.centerY.equalTo(navCenterY)
make.left.equalToSuperview().offset(marginLR)
make.width.height.equalTo(iconWH)
}
proBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: iconWH))
proBtn.setBackgroundImage(UIImage(named: "home_pro_star_back"), for: .normal)
proBtn.addTarget(self, action: #selector(proBtnClick), for: .touchUpInside)
self.addSubview(proBtn)
proBtn.snp.makeConstraints { make in
make.centerY.equalTo(navCenterY)
make.right.equalToSuperview().offset(-15)
make.width.equalTo(70)
make.height.equalTo(iconWH)
}
}
@objc private func backBtnClick() {
self.responderViewController()?.navigationController?.popViewController(animated: true)
}
@objc private func proBtnClick() {
let homeNavViewModel = HomeNavViewModel()
let vc = HomePayViewController()
vc.modalPresentationStyle = .fullScreen
homeNavViewModel.presentToDetailController(currentView: self, destnationController: vc)
}
}
//
// CompressSortView.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import Foundation
class CompressSortView : UIView,UITableViewDelegate,UITableViewDataSource {
var currentIndex : Int = 0
let tableData :[String] = ["Largest","Smallest","Newest","Oldest"]
var callBack : callBack<Any> = {sortType in}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : CompressSortCell = tableView.dequeueReusableCell(withIdentifier: "CompressSortCell",for: indexPath) as! CompressSortCell
cell.cellTag = indexPath.row
cell.selectButton.setTitle(tableData[indexPath.row], for: .normal)
cell.callBack = {[weak self] cellTag in
guard let self else {return}
self.currentIndex = cellTag as! Int
self.tableView.reloadData()
}
if indexPath.row == currentIndex {
cell.selectButton.layer.borderWidth = 1.0
cell.selectButton.setTitleColor(UIColor(red: 0, green: 0.51, blue: 1, alpha: 1), for: .normal)
}else{
cell.selectButton.layer.borderWidth = 0
cell.selectButton.setTitleColor(UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1), for: .normal)
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 48 * RScreenW()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(self.backView)
self.backView.addSubview(self.selectedView)
self.selectedView.addSubview(self.lineView)
self.selectedView.addSubview(self.titleLabel)
self.selectedView.addSubview(self.tableView)
self.selectedView.addSubview(self.applyButton)
self.backView.snp.makeConstraints { make in
make.top.left.right.bottom.equalToSuperview()
}
self.selectedView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(416)
}
self.lineView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(16)
make.width.equalTo(57)
make.height.equalTo(4)
make.centerX.equalToSuperview()
}
self.titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.top.equalTo(self.lineView.snp.bottom).offset(20)
make.height.equalTo(20)
}
self.tableView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.top.equalTo(self.titleLabel.snp.bottom).offset(4)
make.height.equalTo(240)
}
self.applyButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
make.bottom.equalToSuperview().offset(-46)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var backView : UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5000)
return view
}()
lazy var selectedView : UIView = {
let view = UIView()
view.backgroundColor = .white
return view
}()
lazy var lineView : UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.85, green: 0.85, blue: 0.85, alpha: 1)
return view
}()
lazy var titleLabel : UILabel = {
let view = UILabel()
view.text = "Sort by"
view.textAlignment = .left
view.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
view.font = UIFont.systemFont(ofSize: 14, weight: .bold)
return view
}()
lazy var tableView : UITableView = {
let view = UITableView()
view.register(CompressSortCell.classForCoder(), forCellReuseIdentifier: "CompressSortCell")
view.backgroundColor = .clear
view.separatorStyle = .none
view.showsVerticalScrollIndicator = false
view.delegate = self
view.dataSource = self
view.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
if #available(iOS 15.0, *) {
view.sectionHeaderTopPadding = 0
}
return view
}()
lazy var applyButton : UIButton = {
let view = UIButton(type: .custom)
view.setTitle("Apply", for: .normal)
view.layer.cornerRadius = 8
view.clipsToBounds = true
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
view.setTitleColor(.white, for: .normal)
view.addTarget(self, action: #selector(applyAction), for: .touchUpInside)
return view
}()
@objc func applyAction(){
// 传给上层控制器,对照片进行排序
callBack(currentIndex)
// 移除自身
self.removeFromSuperview()
}
}
//
// CpmpressSwitchView.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import Foundation
class CompressSwitchView : UIView {
var currentButton : UIButton?
lazy var leftButton : UIButton = {
let button = UIButton()
button.layer.cornerRadius = 4
button.clipsToBounds = true
button.setTitle("Photos", for: .normal)
button.addTarget(self, action: #selector(selectedButtonAction(_:)), for: .touchUpInside)
button.setTitleColor(UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1), for: .normal)
return button
}()
lazy var rightButton : UIButton = {
let button = UIButton()
button.layer.cornerRadius = 4
button.clipsToBounds = true
button.setTitle("Videos", for: .normal)
button.addTarget(self, action: #selector(selectedButtonAction(_:)), for: .touchUpInside)
button.setTitleColor(UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1), for: .normal)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .clear
self.addSubview(self.leftButton)
self.addSubview(self.rightButton)
self.leftButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(4)
make.top.equalToSuperview().offset(4)
make.bottom.equalToSuperview().offset(-4)
make.width.equalTo(self.snp.width).multipliedBy(0.5).offset(-6)
}
self.rightButton.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-4)
make.top.equalToSuperview().offset(4)
make.bottom.equalToSuperview().offset(-4)
make.left.equalTo(self.leftButton.snp.right).offset(4)
}
// 初始化的时候设置默认值
self.currentButton = self.leftButton
self.currentButton?.setTitleColor(UIColor(red: 0, green: 0.51, blue: 1, alpha: 1), for: .normal)
self.currentButton?.backgroundColor = .white
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func selectedButtonAction(_ sender : UIButton){
if sender != self.currentButton{
self.currentButton?.setTitleColor(UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1), for: .normal)
self.currentButton?.backgroundColor = .clear
}
sender.setTitleColor(UIColor(red: 0, green: 0.51, blue: 1, alpha: 1), for: .normal)
sender.backgroundColor = .white
self.currentButton = sender
}
}
//
// CompressTipView.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class CompressTipView : UIView {
var callBack:callBack<Any> = {allow in}
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(self.backView)
self.backView.addSubview(self.contentView)
self.contentView.addSubview(self.tipLabel)
self.contentView.addSubview(self.detailTiplabel)
self.contentView.addSubview(self.shotView)
self.contentView.addSubview(self.noAllowBtn)
self.contentView.addSubview(self.lineView)
self.contentView.addSubview(self.deleteBtn)
self.backView.snp.makeConstraints { make in
make.width.height.left.top.equalToSuperview()
}
self.contentView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(53)
make.right.equalToSuperview().offset(-53)
make.height.equalTo(310)
make.centerY.equalToSuperview()
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(16)
make.left.equalToSuperview().offset(16)
make.right.equalToSuperview().offset(-16)
make.height.equalTo(44)
}
self.detailTiplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipLabel.snp.bottom).offset(2)
make.left.equalToSuperview().offset(16)
make.right.equalToSuperview().offset(-16)
make.height.equalTo(36)
}
self.shotView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(16)
make.left.equalToSuperview().offset(16)
make.right.equalToSuperview().offset(-16)
make.height.equalTo(152)
}
self.noAllowBtn.snp.makeConstraints { make in
make.bottom.equalToSuperview()
make.left.equalToSuperview()
make.width.equalTo(134.25)
make.height.equalTo(44)
}
self.lineView.snp.makeConstraints { make in
make.bottom.equalToSuperview()
make.centerX.equalTo(self.shotView.snp.centerX)
make.width.equalTo(2)
make.height.equalTo(44)
}
self.deleteBtn.snp.makeConstraints { make in
make.bottom.equalToSuperview()
make.right.equalToSuperview()
make.width.equalTo(134.25)
make.height.equalTo(44)
}
}
lazy var backView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5000)
return view
}()
lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.clipsToBounds = true
view.layer.cornerRadius = 14
return view
}()
lazy var tipLabel: UILabel = {
let label = UILabel()
label.text = "Allow ”Al Cleaner“ to delete2 photos?"
label.textAlignment = .center
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 17, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "These photos will be deleted from iCloud Photos on all your devices."
label.textAlignment = .center
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 13, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var shotView: UIView = {
let view = UIView()
view.backgroundColor = .gray
return view
}()
lazy var noAllowBtn: UIButton = {
let button = UIButton()
button.setTitle("Don't Allow", for: .normal)
button.setTitleColor(UIColor(red: 0, green: 0.48, blue: 1, alpha: 1), for: .normal)
button.addTarget(self, action: #selector(noAllowClick), for: .touchUpInside)
return button
}()
lazy var lineView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.24, green: 0.24, blue: 0.26, alpha: 0.3600)
return view
}()
lazy var deleteBtn: UIButton = {
let button = UIButton()
button.setTitle("Delete", for: .normal)
button.setTitleColor(UIColor(red: 0, green: 0.48, blue: 1, alpha: 1), for: .normal)
button.addTarget(self, action: #selector(deleteClick), for: .touchUpInside)
return button
}()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func noAllowClick(){
self.removeFromSuperview()
callBack(false)
}
@objc func deleteClick(){
self.removeFromSuperview()
callBack(true)
}
}
//
// CompressingViewController.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class CompressingView: UIView{
var data: [ResourceModel]?
override init(frame: CGRect) {
super.init(frame: frame)
setUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var backView:UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
return view
}()
lazy var animationView:CircularProgressBar = {
let progressBar = CircularProgressBar()
progressBar.progressColor = UIColor.white
progressBar.trackColor = UIColor.colorWithHex(hexStr: "#2B85FF")
progressBar.lineWidth = 20
return progressBar
}()
lazy var tipLabel:UILabel = {
let view = UILabel()
view.text = "We're freeing up space on your device."
view.textAlignment = .center
view.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
return view
}()
func setUI(){
self.addSubview(self.backView)
self.addSubview(self.animationView)
self.addSubview(self.tipLabel)
self.backView.snp.makeConstraints { make in
make.top.bottom.left.right.equalToSuperview()
}
self.animationView.snp.makeConstraints { make in
make.width.height.equalTo(180)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(156)
}
self.tipLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.centerX.equalToSuperview()
make.top.equalTo(self.animationView.snp.bottom).offset(95)
}
}
}
//
// QualityView.swift
// PhoneManager
//
// Created by edy on 2025/4/2.
//
import Foundation
class QualityView : UIView{
var type : Int = 0
var callBack : callBack<Any> = {type in}
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.layer.cornerRadius = 12
self.clipsToBounds = true
self.addSubview(self.tipLabel)
self.addSubview(self.detailTiplabel)
self.addSubview(self.selectedImageView)
self.tipLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.top.equalToSuperview().offset(12)
make.width.equalTo(276)
make.height.equalTo(20)
}
self.detailTiplabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.bottom.equalToSuperview().offset(-12)
make.width.equalTo(276)
make.height.equalTo(17)
}
self.selectedImageView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-16)
make.centerY.equalToSuperview()
make.width.equalTo(24)
make.height.equalTo(24)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var tipLabel: UILabel = {
let label = UILabel()
label.text = "Low quality"
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "Compress up to 80% of the size"
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var selectedImageView: UIImageView = {
let imageView = UIImageView()
imageView.backgroundColor = .clear
imageView.image = UIImage(named: "ic_sel_com")
imageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(selectClick))
imageView.addGestureRecognizer(tap)
return imageView
}()
@objc func selectClick(){
callBack(self.type)
}
}
//
// CompressViewModel.swift
// PhoneManager
//
// Created by edy on 2025/4/3.
//
import Foundation
import Photos
typealias Finished = ([ResourceModel])->Void
class CompressViewModel{
func processData(finised: @escaping() -> Void) {
// 模拟异步操作
DispatchQueue.global().async {
// 模拟耗时操作
Thread.sleep(forTimeInterval: 2)
finised()
}
}
/// 获取所有图片信息
/// - Returns: 图片信息
func getAllPhotos(_ finished : @escaping Finished){
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let photosAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
// 获取到了所有图片的assets
let assetsArray = photosAssets.objects(at: IndexSet(0..<photosAssets.count))
// 初始化一个model数组
var models : [ResourceModel] = []
let options = PHImageRequestOptions()
options.isSynchronous = false
options.deliveryMode = .highQualityFormat
for asset in assetsArray {
PHImageManager.default().requestImageDataAndOrientation(for: asset, options: options) { (imageData, _, _, _) in
if let data = imageData {
// 图片大小
let sizeInBytes = Double(data.count)
let sizeInMB = sizeInBytes / (1024 * 1024)
// 获取图片的日期
let creationDate = asset.creationDate
// 获取图片的localIdentifier
let localIdentifier = asset.localIdentifier
// 计算压缩后的大小
PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode:.aspectFit, options: options) { (image, _) in
if let originalImage = image {
// 项目中用到的是【0.2、0.5和0.8】,这里我们初始化的时候使用0.2去计算
if let compressedData = originalImage.jpegData(compressionQuality: 0.2) {
let compressCompletedSize = Double(compressedData.count) / (1024 * 1024)
// 构建model
let model = ResourceModel(ident: localIdentifier, compressSize: compressCompletedSize, orgSize: sizeInMB, createDate: creationDate!,imageAsset: asset)
models.append(model)
finished(models)
}
}
}
}
}
}
}
/// 对资源进行排序
/// - Parameters:
/// - resource: 原资源
/// - sortType: 排序的类型,升序或者降序。0-升序,1-降序
/// - sortKind: 排序的种类 大小或者时间 0-大小,1-时间
/// - Returns: 返回排序结果
func sortRsource(resource:[ResourceModel],sortType:Int,sortKind:Int)->[ResourceModel]{
if sortKind == 0 {
if sortType == 0 {
return resource.sorted { $0.orgSize < $1.orgSize }
}else{
return resource.sorted { $0.orgSize > $1.orgSize }
}
}else{
if sortType == 0 {
return resource.sorted { $0.createDate < $1.createDate }
}else{
return resource.sorted { $0.createDate > $1.createDate }
}
}
}
/// 压缩多张图片
/// - Parameters:
/// - assets: 图片集合
/// - compressionQuality: 图片质量
/// - progressHandler: 进度
/// - completion: 完成
func compress(assets: [ResourceModel], compressionQuality : CGFloat, progressHandler: @escaping (Float) -> Void, completion: @escaping ([Data?], [Error?]) -> Void) {
var compressedDataArray: [Data?] = Array(repeating: nil, count: assets.count)
var errorArray: [Error?] = Array(repeating: nil, count: assets.count)
var completedCount = 0
let totalCount = assets.count
for (index, model) in assets.enumerated() {
compressSingleAsset(model.imageAsset,compressionQuality) { (progress) in
let singleProgress = Float(completedCount) / Float(totalCount) + progress / Float(totalCount)
progressHandler(singleProgress)
} completion: { (compressedData, error) in
compressedDataArray[index] = compressedData
errorArray[index] = error
completedCount += 1
if completedCount == totalCount {
completion(compressedDataArray, errorArray)
}
}
}
}
private func compressSingleAsset(_ asset: PHAsset,_ compressionQuality : CGFloat, progress: @escaping (Float) -> Void, completion: @escaping (Data?, Error?) -> Void) {
let options = PHImageRequestOptions()
options.isSynchronous = false
options.deliveryMode = .highQualityFormat
PHImageManager.default().requestImageDataAndOrientation(for: asset, options: options) { (imageData, _, _, error) in
if let error = error {
completion(nil, error as? Error)
return
}
guard let originalData = imageData else {
completion(nil, nil)
return
}
let totalSize = originalData.count
var processedSize = 0
self.compressData(originalData, compressionQuality: compressionQuality) { (progressValue) in
processedSize = Int(Float(totalSize) * progressValue)
let currentProgress = Float(processedSize) / Float(totalSize)
progress(currentProgress)
} completion: { (compressedData, error) in
completion(compressedData, error)
}
}
}
private func compressData(_ data: Data, compressionQuality: CGFloat, progress: @escaping (Float) -> Void, completion: @escaping (Data?, Error?) -> Void) {
guard let originalImage = UIImage(data: data) else {
completion(nil, nil)
return
}
DispatchQueue.global().async {
var progressValue: Float = 0
let step = 0.1
while progressValue < 1 {
progress(progressValue)
progressValue += Float(step)
Thread.sleep(forTimeInterval: 0.1)
}
if let compressedData = originalImage.jpegData(compressionQuality: compressionQuality) {
DispatchQueue.main.async {
progress(1.0)
completion(compressedData, nil)
}
} else {
DispatchQueue.main.async {
completion(nil, nil)
}
}
}
}
}
......@@ -57,15 +57,10 @@ class HomeViewController:BaseViewController {
DispatchQueue.main.async { [weak self] in
guard let self else {return}
let vc:SecretViewController = SecretViewController()
self.navigationController?.pushViewController(vc, animated: true)
}
break
case 2:
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
let vc = WidgetViewController()
case 2 :
DispatchQueue.main.async {[weak self] in
guard let self else {return}
let vc:CompressController = CompressController()
self.navigationController?.pushViewController(vc, animated: true)
}
break
......
......@@ -9,16 +9,6 @@
"heightImage": "tabbar_secret_hight",
"text":"Secret Space",
},
{
"normalImage": "ic_contacts_home_pre",
"heightImage": "tabbar_contacts_high",
"text":"Contacts",
},
{
"normalImage": "ic_email_home_pre",
"heightImage": "tabbar_email_high",
"text":"Email Cleaner",
},
{
"normalImage": "ic_cmpress_home_pre",
"heightImage": "tabbar_cmpress_high",
......
......@@ -57,7 +57,7 @@ class HomeNavView:UIView {
proBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: iconWH))
proBtn.setBackgroundImage(UIImage(named: "home_pro_star_back"), for: .normal)
proBtn.addTarget(self, action: #selector(settingBtnClick), for: .touchUpInside)
proBtn.addTarget(self, action: #selector(proBtnClick), for: .touchUpInside)
self.addSubview(proBtn)
proBtn.snp.makeConstraints { make in
......@@ -79,9 +79,18 @@ class HomeNavView:UIView {
}
@objc private func settingBtnClick() {
let homeNavViewModel = HomeNavViewModel()
let settingViewController = SettingViewController()
homeNavViewModel.pushToDetailController(currentView: self, destnationController: settingViewController)
}
@objc private func proBtnClick() {
let homeNavViewModel = HomeNavViewModel()
let vc = HomePayViewController()
vc.modalPresentationStyle = .fullScreen
homeNavViewModel.presentToDetailController(currentView: self, destnationController: vc)
}
func setFileAndCount(count:Int,fileSize:Double) {
......
......@@ -53,6 +53,8 @@ class PhotoDataManager {
private func loadDataFromPhotos(resultModel:@escaping (_ model:PhotosManagerModel) -> () = {mdoel in}) {
PhotoAndVideoMananger.mananger.setAssets()
let model1:HomePhotosModel = HomePhotosModel(folderName: PhotsFileType.duplicates.rawValue, allFileSize: 0, assets: [])
let model2:HomePhotosModel = HomePhotosModel(folderName: PhotsFileType.similar.rawValue, allFileSize: 0, assets: [])
......@@ -71,6 +73,7 @@ class PhotoDataManager {
resultModel(allModel)
PhotoAndVideoMananger.mananger.fetXSOther { array in
let dispatchGroup = DispatchGroup()
......@@ -96,13 +99,16 @@ class PhotoDataManager {
dispatchGroup.leave()
}
dispatchGroup.enter()
model2.assets = [ResourceManager.manager.getAllVideo()]
dispatchGroup.leave()
dispatchGroup.enter()
PhotoAndVideoMananger.mananger.fetXSVideo { array in
PhotoSimilarityFinder.processSimilarVideoGroups(videoGroups: array) {ids in
model3.assets = ids
model4.assets = ids
resultModel(allModel)
......@@ -110,6 +116,10 @@ class PhotoDataManager {
}
}
dispatchGroup.notify(queue: .main) {
print("所有异步操作都已完成")
......
......@@ -2,6 +2,9 @@ import UIKit
class HomeOtherCollectionCell: UICollectionViewCell {
var similarFlag : Bool = false
// MARK: - Properties
static let identifier = "HomeOtherCollectionCellID"
......@@ -14,22 +17,39 @@ class HomeOtherCollectionCell: UICollectionViewCell {
return iv
}()
private let countLabel: UILabel = {
private let infoBackView: UIView = {
let iv = UIView()
iv.clipsToBounds = true
iv.layer.cornerRadius = 8
iv.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
return iv
}()
let countLabel: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = .systemFont(ofSize: 16, weight: .medium)
label.textAlignment = .center
label.font = .systemFont(ofSize: 10, weight: .medium)
label.textAlignment = .left
return label
}()
private let sizeLabel: UILabel = {
let sizeLabel: UILabel = {
let label = UILabel()
label.textColor = .systemGray
label.font = .systemFont(ofSize: 12)
label.textColor = UIColor(red: 0.6, green: 0.8, blue: 1, alpha: 1)
label.font = .systemFont(ofSize: 8, weight: .regular)
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)
......@@ -52,11 +72,14 @@ class HomeOtherCollectionCell: UICollectionViewCell {
// MARK: - Setup
private func setupUI() {
backgroundColor = UIColor.colorWithHex(hexStr: "#F2F6FC")
self.contentView.addSubview(self.titleLabel)
self.contentView.addSubview(self.imageView)
self.imageView.addSubview(self.infoBackView)
self.infoBackView.addSubview(self.countLabel)
self.infoBackView.addSubview(self.sizeLabel)
self.infoBackView.addSubview(self.moreImageView)
contentView.addSubview(imageView)
contentView.addSubview(countLabel)
contentView.addSubview(sizeLabel)
contentView.addSubview(titleLabel)
}
......@@ -87,14 +110,14 @@ class HomeOtherCollectionCell: UICollectionViewCell {
func configure(with image: UIImage?, count: Int, size: String) {
imageView.image = image
countLabel.text = "\(count) Photos"
sizeLabel.text = size
sizeLabel.text = "(\(size)) MB"
}
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
countLabel.text = nil
sizeLabel.text = nil
countLabel.text = "0 Photos"
sizeLabel.text = "(0.0) MB"
}
override func layoutSubviews() {
......@@ -103,12 +126,17 @@ class HomeOtherCollectionCell: UICollectionViewCell {
self.layer.masksToBounds = true
imageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().offset(-16)
make.width.equalToSuperview().offset(-32)
make.height.equalTo(self.width - 32)
}
self.infoBackView.snp.makeConstraints { make in
make.right.bottom.equalToSuperview()
make.height.equalTo(40)
make.width.equalTo(114)
}
......@@ -118,6 +146,24 @@ class HomeOtherCollectionCell: UICollectionViewCell {
make.width.equalToSuperview().offset(-32)
}
self.countLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalToSuperview().offset(4)
make.width.equalTo(68)
make.height.equalTo(20)
}
self.sizeLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalTo(countLabel.snp.bottom).offset(0)
make.width.equalTo(68)
make.height.equalTo(14)
}
self.moreImageView.snp.makeConstraints { make in
make.width.height.equalTo(20)
make.right.equalToSuperview().offset(-12)
make.centerY.equalToSuperview()
}
titleLabel.sizeToFit()
}
}
//
// HomeNavViewModel.swift
// PhoneManager
//
// Created by edy on 2025/3/28.
//
import Foundation
class HomeNavViewModel{
func pushToDetailController(currentView : UIView, destnationController: BaseViewController) {
let navigationController = currentView.responderViewController()?.navigationController
navigationController?.pushViewController(destnationController, animated: true)
}
func presentToDetailController(currentView : UIView, destnationController: UIViewController) {
let vc = currentView.responderViewController()?.navigationController
vc?.present(destnationController, animated: true)
}
}
......@@ -41,7 +41,7 @@ class HomePayViewController:UIViewController {
switch operstatus {
case .close:
self.navigationController?.dismiss(animated: true)
self.dismiss(animated: true)
default:
break
}
......
//
// SettingModel.swift
// PhoneManager
//
// Created by edy on 2025/3/31.
//
import Foundation
struct SettingModel {
var sectionTitle: String
var rowInfo : [RowInfoModel]
init(sectionTitle: String, rowInfo: [RowInfoModel]) {
self.sectionTitle = sectionTitle
self.rowInfo = rowInfo
}
}
struct RowInfoModel{
var imageName : String
var title: String
init(imageName: String, title: String) {
self.imageName = imageName
self.title = title
}
}
func getSettingViewInfo() -> [SettingModel] {
return [
// SettingModel(sectionTitle: "",rowInfo: [RowInfoModel(imageName: "",title: "")]),
// SettingModel(sectionTitle: "FROM DEVELOPER",rowInfo:
// [RowInfoModel(imageName: "ic_more_setting",title: "More Apps From Us")]),
// SettingModel(sectionTitle: "EMAIL",rowInfo:
// [RowInfoModel(imageName: "ic_out_setting",title: "Sign Out")]),
// SettingModel(sectionTitle: "UTILITIES",rowInfo:
// [RowInfoModel(imageName: "ic_widgets_setting",title: "Widgets")]),
// SettingModel(sectionTitle: "SECRET SPACE",rowInfo: [
// RowInfoModel(imageName: "ic_pin_setting",title: "Use PIN"),
// RowInfoModel(imageName: "ic_delete_setting",title: "Remove After lmport")]),
// SettingModel(sectionTitle: "OTHERS",rowInfo:
// [RowInfoModel(imageName: "ic_vibration_setting",title: "Vibration"),
// RowInfoModel(imageName: "ic_list_setting",title: "Keep List"),
// RowInfoModel(imageName: "ic_hints_setting",title: "Hints")]),
// SettingModel(sectionTitle: "SUPPORT",rowInfo:
// [RowInfoModel(imageName: "ic_faq_setting",title: "FAQ"),
// RowInfoModel(imageName: "ic_email_setting",title: "Email Support"),
// RowInfoModel(imageName: "ic_restore_setting",title: "Restore Purchase"),
// RowInfoModel(imageName: "ic_about_setting",title: "About Us"),
// RowInfoModel(imageName: "ic_privacy_setting",title: "Privacy Policy")]),
// SettingModel(sectionTitle: "STAY IN TOUCH",rowInfo:
// [RowInfoModel(imageName: "ic_rate_setting",title: "Rate App"),
// RowInfoModel(imageName: "ic_share_setting",title: "Share App"),
// RowInfoModel(imageName: "ic_ins_setting",title: "Follow on Instagram")])]
SettingModel(sectionTitle: "",rowInfo: [RowInfoModel(imageName: "",title: "")]),
SettingModel(sectionTitle: "FROM DEVELOPER",rowInfo:
[RowInfoModel(imageName: "ic_more_setting",title: "More Apps From Us")]),
SettingModel(sectionTitle: "UTILITIES",rowInfo:
[RowInfoModel(imageName: "ic_widgets_setting",title: "Widgets")]),
SettingModel(sectionTitle: "SECRET SPACE",rowInfo: [
RowInfoModel(imageName: "ic_pin_setting",title: "Use PIN")]),
SettingModel(sectionTitle: "STAY IN TOUCH",rowInfo:
[RowInfoModel(imageName: "ic_rate_setting",title: "Rate App"),
RowInfoModel(imageName: "ic_share_setting",title: "Share App"),
RowInfoModel(imageName: "ic_ins_setting",title: "Follow on Instagram")])]
}
//
// SettingNormalCell.swift
// PhoneManager
//
// Created by edy on 2025/3/31.
//
import Foundation
class SettingNormalCell : UITableViewCell {
override var frame: CGRect{
didSet{
var newFrame = frame
newFrame.origin.x += 15
newFrame.size.width -= 30
super.frame = newFrame
}
}
lazy var lineView : UIView = {
let lineView = UIView()
lineView.backgroundColor = .white
return lineView
}()
lazy var logoView : UIImageView = {
let logoView = UIImageView()
logoView.backgroundColor = .clear
return logoView
}()
lazy var fLabel : UILabel = {
let label = UILabel();
label.text = "ceshi"
label.font = UIFont(name: "PingFang SC-Bold", size: 14)
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.textAlignment = .left
return label
}()
lazy var moreImageView : UIImageView = {
let sview:UIImageView = UIImageView()
sview.backgroundColor = .clear
sview.image = UIImage(named: "icon_left_setting_grey")
return sview
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
self.contentView.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.contentView.addSubview(self.logoView)
self.contentView.addSubview(self.fLabel)
self.contentView.addSubview(self.moreImageView)
self.contentView.addSubview(self.lineView)
self.logoView.snp.makeConstraints { make in
make.width.height.equalTo(28)
make.left.equalToSuperview().offset(16)
make.centerY.equalToSuperview()
}
self.fLabel.snp.makeConstraints { make in
make.left.equalTo(self.logoView.snp.right).offset(4)
make.centerY.equalToSuperview();
make.height.equalTo(20)
make.width.equalTo(206)
}
self.moreImageView.snp.makeConstraints { make in
make.width.height.equalTo(20)
make.right.equalToSuperview().offset(-16)
make.centerY.equalToSuperview()
}
self.lineView.snp.makeConstraints { make in
make.height.equalTo(1)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.bottom.equalToSuperview().offset(-1)
}
}
required init?(coder: NSCoder) {
super .init(coder: coder)
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
}
}
//
// SettingSwitchCell.swift
// PhoneManager
//
// Created by edy on 2025/3/31.
//
import Foundation
class SettingSwitchCell : UITableViewCell {
override var frame: CGRect{
didSet{
var newFrame = frame
newFrame.origin.x += 15
newFrame.size.width -= 30
super.frame = newFrame
}
}
lazy var lineView : UIView = {
let lineView = UIView()
lineView.backgroundColor = .white
return lineView
}()
lazy var logoView : UIImageView = {
let logoView = UIImageView()
logoView.backgroundColor = .clear
return logoView
}()
lazy var fLabel : UILabel = {
let label = UILabel();
label.text = "ceshi"
label.font = UIFont(name: "PingFang SC-Bold", size: 14)
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.textAlignment = .left
return label
}()
lazy var openImageView : UIImageView = {
let sview:UIImageView = UIImageView()
sview.backgroundColor = .clear
sview.image = UIImage(named: "button_switch_off")
return sview
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
self.contentView.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.contentView.addSubview(self.logoView)
self.contentView.addSubview(self.fLabel)
self.contentView.addSubview(self.openImageView)
self.contentView.addSubview(self.lineView)
self.logoView.snp.makeConstraints { make in
make.width.height.equalTo(28)
make.left.equalToSuperview().offset(16)
make.centerY.equalToSuperview()
}
self.fLabel.snp.makeConstraints { make in
make.left.equalTo(self.logoView.snp.right).offset(4)
make.centerY.equalToSuperview();
make.height.equalTo(20)
make.width.equalTo(206)
}
self.openImageView.snp.makeConstraints { make in
make.height.equalTo(28)
make.width.equalTo(36)
make.right.equalToSuperview().offset(-16)
make.centerY.equalToSuperview()
}
self.lineView.snp.makeConstraints { make in
make.height.equalTo(1)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.bottom.equalToSuperview().offset(-1)
}
}
required init?(coder: NSCoder) {
super .init(coder: coder)
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
}
}
//
// SettingViewHeaderCell.swift
// PhoneManager
//
// Created by edy on 2025/3/28.
//
import Foundation
class SettingViewHeaderCell : UITableViewCell {
lazy var logoView : UIImageView = {
let logoView = UIImageView()
logoView.layer.cornerRadius = 22.5
logoView.contentMode = .scaleAspectFit
logoView.translatesAutoresizingMaskIntoConstraints = false
logoView.image = UIImage(named: "logo_phone_manager")
return logoView
}()
lazy var fLabel : UILabel = {
let label = UILabel();
label.text = "Unlock Unlimited Access"
label.font = UIFont(name: "PingFang SC-Bold", size: 18)
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.textAlignment = .center
return label
}()
lazy var sLabel : UILabel = {
let label = UILabel();
label.text = "Enjoy unlimited access with all Cleanup features"
label.font = UIFont(name: "PingFang SC-Regular", size: 14)
label.textColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1)
label.textAlignment = .center
return label
}()
lazy var preButtonImageView : UIImageView = {
let preButtonImageView = UIImageView()
preButtonImageView.image = UIImage(named: "img_light_setting")
preButtonImageView.backgroundColor = .clear
preButtonImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(leanMoreBtnClick))
preButtonImageView.addGestureRecognizer(tap)
return preButtonImageView
}()
lazy var moreButton : UIButton = {
let sview:UIButton = UIButton()
sview.backgroundColor = UIColor.colorWithHex(hexStr: mColor)
sview.setTitle("Learn More", for: .normal)
sview.setTitleColor(UIColor.white, for: .normal)
sview.titleLabel?.font = .systemFont(ofSize: 16, weight: .bold)
sview.layer.cornerRadius = 23
sview.layer.masksToBounds = true
sview.addTarget(self, action: #selector(leanMoreBtnClick), for: .touchUpInside)
return sview
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
self.contentView.addSubview(self.logoView)
self.contentView.addSubview(self.fLabel)
self.contentView.addSubview(self.sLabel)
self.contentView.addSubview(self.moreButton)
self.moreButton.addSubview(self.preButtonImageView)
self.logoView.snp.makeConstraints { make in
make.width.height.equalTo(150)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(48)
}
self.fLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.top.equalTo(self.logoView.snp.bottom).offset(40)
make.height.equalTo(25)
}
self.sLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.top.equalTo(fLabel.snp.bottom).offset(4)
make.height.equalTo(20)
}
self.preButtonImageView.snp.makeConstraints { make in
make.width.height.equalTo(46)
make.left.equalToSuperview().offset(6)
make.top.equalToSuperview()
}
self.moreButton.snp.makeConstraints { make in
make.width.equalTo(245)
make.height.equalTo(46)
make.centerX.equalToSuperview()
make.top.equalTo(self.sLabel.snp.bottom).offset(20)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func leanMoreBtnClick() {
let homeNavViewModel = HomeNavViewModel()
let vc = HomePayViewController()
vc.modalPresentationStyle = .fullScreen
homeNavViewModel.presentToDetailController(currentView: self, destnationController: vc)
}
}
//
// SignOutTipView.swift
// PhoneManager
//
// Created by edy on 2025/3/31.
//
import Foundation
class SignOutTipView : UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(backView)
self.backView.addSubview(self.contentView)
self.contentView.addSubview(self.logoView)
self.contentView.addSubview(self.fLabel)
self.contentView.addSubview(self.yesButton)
self.contentView.addSubview(self.cancelButton)
self.contentView.snp.makeConstraints { make in
make.width.equalTo(295)
make.height.equalTo(370)
make.center.equalToSuperview()
}
self.logoView.snp.makeConstraints { make in
make.width.equalTo(192)
make.height.equalTo(158)
make.top.equalToSuperview().offset(28)
make.centerX.equalToSuperview()
}
self.fLabel.snp.makeConstraints { make in
make.top.equalTo(self.logoView.snp.bottom).offset(0)
make.left.equalToSuperview().offset(24)
make.right.equalToSuperview().offset(-24)
make.height.equalTo(56)
}
self.yesButton.snp.makeConstraints { make in
make.top.equalTo(self.fLabel.snp.bottom).offset(16)
make.left.equalToSuperview().offset(24)
make.right.equalToSuperview().offset(-24)
make.height.equalTo(46)
}
self.cancelButton.snp.makeConstraints { make in
make.top.equalTo(self.yesButton.snp.bottom).offset(4)
make.left.equalToSuperview().offset(24)
make.right.equalToSuperview().offset(-24)
make.height.equalTo(46)
}
}
lazy var backView : UIView = {
let maskView = UIView(frame: self.bounds)
maskView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5000)
return maskView
}()
lazy var contentView : UIView = {
let contentView = UIView(frame: self.bounds)
contentView.backgroundColor = .white
contentView.layer.cornerRadius = 20
contentView.layer.masksToBounds = true
return contentView
}()
lazy var logoView : UIImageView = {
let logoView = UIImageView()
logoView.image = UIImage(named: "img_return_pop")
logoView.backgroundColor = .clear
return logoView
}()
lazy var fLabel : UILabel = {
let label = UILabel();
label.text = "Are you sure you want to sign out?"
label.font = UIFont(name: "PingFang SC-Bold", size: 20)
label.textColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 1)
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
lazy var yesButton : UIButton = {
let sview:UIButton = UIButton()
sview.backgroundColor = UIColor.colorWithHex(hexStr: mColor)
sview.setTitle("Yes", for: .normal)
sview.setTitleColor(UIColor.white, for: .normal)
sview.titleLabel?.font = .systemFont(ofSize: 16, weight: .bold)
sview.layer.cornerRadius = 23
sview.layer.masksToBounds = true
return sview
}()
lazy var cancelButton : UIButton = {
let sview:UIButton = UIButton()
sview.backgroundColor = .white
sview.setTitle("Cancel", for: .normal)
sview.setTitleColor(UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1), for: .normal)
sview.titleLabel?.font = UIFont(name: "PingFang SC-Bold", size: 16)
sview.layer.cornerRadius = 23
sview.layer.masksToBounds = true
sview.addTarget(self, action: #selector(clickCancelAction), for: UIControl.Event.touchUpInside)
return sview
}()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func clickCancelAction() {
self.removeFromSuperview()
}
}
//
// SettingVieController.swift
// PhoneManager
//
// Created by edy on 2025/3/28.
//
import Foundation
class SettingViewController : BaseViewController , UITableViewDelegate, UITableViewDataSource{
var modelData: [SettingModel]?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
modelData = getSettingViewInfo()
self.tableView.reloadData()
}
lazy var tableView : UITableView = {
let cY = titleView.height + titleView.y
let tableView:UITableView = UITableView.init(frame: CGRect(x: 0, y: cY, width: view.width, height: view.height - cY) , style: UITableView.Style.grouped)
tableView.backgroundColor = .clear
tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(SettingViewHeaderCell.classForCoder(), forCellReuseIdentifier: "SettingViewHeaderCell")
tableView.register(SettingNormalCell.classForCoder(), forCellReuseIdentifier: "SettingNormalCell")
tableView.register(SettingSwitchCell.classForCoder(), forCellReuseIdentifier: "SettingSwitchCell")
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
}
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.titleView.titleLabel.text = "Settings"
self.titleView.titleLabel.textAlignment = .left
self.titleView.titleLabel.font = UIFont(name: "PingFang SC-Bold", size: 20)
self.titleView.titleLabel.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
modelData = getSettingViewInfo()
self.view.addSubview(tableView)
self.tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let model : SettingModel = modelData![section]
return model.rowInfo.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell : SettingViewHeaderCell = tableView.dequeueReusableCell(withIdentifier: "SettingViewHeaderCell",for: indexPath) as! SettingViewHeaderCell
return cell
}else{
let model : SettingModel = modelData![indexPath.section]
let detailModel : RowInfoModel = model.rowInfo[indexPath.row]
if indexPath.section == 3 {
let cell : SettingSwitchCell = tableView.dequeueReusableCell(withIdentifier: "SettingSwitchCell",for: indexPath) as! SettingSwitchCell
cell.fLabel.text = detailModel.title
cell.logoView.image = UIImage(named: detailModel.imageName)
let rowNum = tableView.numberOfRows(inSection: indexPath.section)
cell.layer.mask = nil
cell.lineView.isHidden = false
if rowNum == 1 {
cell.cornerCut(radius: 12, corner: UIRectCorner(rawValue: (UIRectCorner.bottomLeft.rawValue)|(UIRectCorner.bottomRight.rawValue)|(UIRectCorner.topLeft.rawValue)|(UIRectCorner.topRight.rawValue)))
cell.lineView.isHidden = true
}else{
if indexPath.row == 0 {
cell.cornerCut(radius: 12, corner: UIRectCorner(rawValue: (UIRectCorner.topLeft.rawValue)|(UIRectCorner.topRight.rawValue)))
}
if (indexPath.row == rowNum - 1){
cell.lineView.isHidden = true
cell.cornerCut(radius: 12,corner: UIRectCorner(rawValue: (UIRectCorner.bottomLeft.rawValue)|(UIRectCorner.bottomRight.rawValue)))
}
}
return cell
}else{
let cell : SettingNormalCell = tableView.dequeueReusableCell(withIdentifier: "SettingNormalCell",for: indexPath) as! SettingNormalCell
cell.fLabel.text = detailModel.title
cell.logoView.image = UIImage(named: detailModel.imageName)
let rowNum = tableView.numberOfRows(inSection: indexPath.section)
cell.layer.mask = nil
cell.lineView.isHidden = false
if rowNum == 1 {
cell.cornerCut(radius: 12, corner: UIRectCorner(rawValue: (UIRectCorner.bottomLeft.rawValue)|(UIRectCorner.bottomRight.rawValue)|(UIRectCorner.topLeft.rawValue)|(UIRectCorner.topRight.rawValue)))
cell.lineView.isHidden = true
}else{
if indexPath.row == 0 {
cell.cornerCut(radius: 12, corner: UIRectCorner(rawValue: (UIRectCorner.topLeft.rawValue)|(UIRectCorner.topRight.rawValue)))
}
if (indexPath.row == rowNum - 1){
cell.lineView.isHidden = true
cell.cornerCut(radius: 12,corner: UIRectCorner(rawValue: (UIRectCorner.bottomLeft.rawValue)|(UIRectCorner.bottomRight.rawValue)))
}
}
return cell
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return modelData!.count
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0{
return 0
}
return 49
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: view.width, height: 49)
view.backgroundColor = .clear
let titleLabel = UILabel()
titleLabel.text = modelData![section].sectionTitle
titleLabel.font = UIFont(name: "PingFang SC-Bold", size: 12)
titleLabel.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
titleLabel.frame = CGRect(x: 15, y: 20, width: 345, height: 17)
view.addSubview(titleLabel)
return view
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 {
return 385
}
return 60
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let signOutTipView = SignOutTipView(frame: self.view.frame)
self.view.addSubview(signOutTipView)
}
}
......@@ -42,6 +42,8 @@ class PhotoAndVideoMananger {
var allAssets:[PHAsset] = []
var screenShotAssets:[PHAsset] = []
var imageAssets:[PHAsset] = []
var videoAssets:[PHAsset] = []
......@@ -56,16 +58,24 @@ class PhotoAndVideoMananger {
let videoAllAssets = PHAsset.fetchAssets(with: .video, options: fetchOptions)
let fetchOptionsS = PHFetchOptions()
fetchOptionsS.predicate = NSPredicate(format: "mediaSubtypes & %d != 0", PHAssetMediaSubtype.photoScreenshot.rawValue)
let screenShotAllAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
let photoAssetsArray = photoAllAssets.objects(at: IndexSet(0..<photoAllAssets.count))
let videoAssetsArray = videoAllAssets.objects(at: IndexSet(0..<videoAllAssets.count))
let screenShotArray = screenShotAllAssets.objects(at: IndexSet(0..<screenShotAllAssets.count))
let combinedArray = photoAssetsArray + videoAssetsArray
imageAssets = photoAssetsArray
videoAssets = videoAssetsArray
screenShotAssets = screenShotArray
allAssets = combinedArray
}
......@@ -187,6 +197,24 @@ class PhotoAndVideoMananger {
}
}
func fetXSScreenShot( resulte:@escaping ([[PHAsset]]) -> Void) {
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "mediaSubtypes & %d != 0", PHAssetMediaSubtype.photoScreenshot.rawValue)
let screenshotAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
let assetsArray = screenshotAssets.objects(at: IndexSet(0..<allAssets.count))
DispatchQueue.global().async {[weak self] in
guard let self = self else { return }
let newArray = self.groupSimilarAssets(from: assetsArray)
resulte(newArray)
}
}
func fetXSVideo( resulte:@escaping ([[PHAsset]]) -> Void) {
let fetchOptions = PHFetchOptions()
......
//
// ResourceManager.swift
// PhoneManager
//
// Created by edy on 2025/4/1.
//
import Foundation
import Photos
class ResourceManager {
static let manager : ResourceManager = ResourceManager()
func getAllPhotos()-> [String]{
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let videoAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
let assetsArray = videoAssets.objects(at: IndexSet(0..<videoAssets.count))
var array : [String] = []
for ass in assetsArray{
array.append(ass.localIdentifier)
}
return array
}
func getAllPhotosByPHAsset()-> [PHAsset]{
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let videoAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions)
let assetsArray = videoAssets.objects(at: IndexSet(0..<videoAssets.count))
return assetsArray
}
/// 获取所有视频
/// - Returns: 视频集合
func getAllVideo() -> [String]{
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let videoAssets = PHAsset.fetchAssets(with: .video, options: fetchOptions)
let assetsArray = videoAssets.objects(at: IndexSet(0..<videoAssets.count))
var array : [String] = []
for ass in assetsArray{
array.append(ass.localIdentifier)
}
return array
}
func getAllVideosByPHAsset()-> [PHAsset]{
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let videoAssets = PHAsset.fetchAssets(with: .video, options: fetchOptions)
let assetsArray = videoAssets.objects(at: IndexSet(0..<videoAssets.count))
return assetsArray
}
}
......@@ -9,8 +9,8 @@ target 'PhoneManager' do
pod 'Alamofire'
pod 'lottie-ios'
pod 'SnapKit'
pod 'OpenCV', '~> 4.0.0'
pod 'HXPhotoPicker'
pod 'OpenCV'
end
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