Commit 1d514222 authored by yqz's avatar yqz

Merge branch 'dev_main' into yQz0507

* dev_main:
  【优化】调整压缩动画以及细节
  fix bug
  fix bugs
  【优化】压缩
parents cb6d4961 470c2abd
......@@ -14,9 +14,9 @@ extension AppDelegate{
func setupDynamicShortcuts() {
let shortcutItem = UIApplicationShortcutItem(
type: "com.app.phonemanager.iap.distance",
localizedTitle: "Unlock Exclusive Discounts",
localizedSubtitle: "Your special offer is awaiting—don't miss this limited-time second chance benefit!",
icon: UIApplicationShortcutIcon(templateImageName: ""), //UIApplicationShortcutIcon(systemImageName: "star.fill"),
localizedTitle: "🎁 Unlock Special Offers",
localizedSubtitle: "A Special Offer Just for You!",
icon: UIApplicationShortcutIcon(systemImageName: "chevron.right"), //UIApplicationShortcutIcon(templateImageName: "icon_gift_sa"), //UIApplicationShortcutIcon(systemImageName: "star.fill"),
userInfo: nil
)
UIApplication.shared.shortcutItems = [shortcutItem]
......
{
"images" : [
{
"filename" : "Group.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "Group_1171275114.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group_1171275114@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group_1171275114@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "Group_1171275116.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group_1171275116@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group_1171275116@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "img_compress.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "img_compress@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "img_compress@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "* 白色实心圆-小.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "* 白色实心圆-小@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "* 白色实心圆-小@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "优惠图标@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "优惠图标@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
......@@ -69,17 +69,6 @@ class CompressSelectCell : UICollectionViewCell {
}
}
var choose : Bool = false {
didSet{
if choose {
self.selectImageView.image = UIImage(named: "ic_unsel_com")
}else{
self.selectImageView.image = UIImage(named: "ic_sel_com")
}
callBack(self.model! ,self.choose)
}
}
lazy var backImageView: UIImageView = {
let view = UIImageView()
......@@ -125,59 +114,14 @@ class CompressSelectCell : UICollectionViewCell {
return view
}()
lazy var extensionView: UIView = {
let view = UIView()
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(selectClick))
view.addGestureRecognizer(tap)
return view
}()
lazy var selectImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_sel_com")
view.backgroundColor = .clear
view.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(selectClick))
view.addGestureRecognizer(tap)
return view
}()
@objc func selectClick(){
// 判断是图片还是视频
if self.currentMediaType == .compressPhoto {
self.choose = !self.choose
}else {
let vc = PMShowImgVideoController()
vc.getVideoURLFromLocalIdentifier(localIdentifier: self.model?.localIdentifier ?? "") {[weak self] url, error in
guard let self else {return}
if url != nil{
self.choose = !self.choose
}else{
let alert = UIAlertController(title: nil, message: "ICloud video cannot be compressed", preferredStyle: .alert)
self.responderViewController()?.present(alert, animated: true, completion: nil)
// 1 秒后关闭弹窗
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
}
}
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(imageClick))
self.addGestureRecognizer(tap)
// self.isUserInteractionEnabled = true
// let tap = UITapGestureRecognizer()
// tap.addTarget(self, action: #selector(imageClick))
// self.addGestureRecognizer(tap)
self.addSubview(self.backImageView)
self.backImageView.addSubview(self.playImageView)
......@@ -185,9 +129,6 @@ class CompressSelectCell : UICollectionViewCell {
self.saveSizeView.addSubview(self.saveSizeLabel)
self.saveSizeView.addSubview(self.moreImageView)
self.addSubview(self.extensionView)
self.addSubview(self.selectImageView)
self.backImageView.snp.makeConstraints { make in
make.left.right.height.width.equalToSuperview()
}
......@@ -214,16 +155,6 @@ class CompressSelectCell : UICollectionViewCell {
make.height.width.equalTo(16)
}
self.selectImageView.snp.makeConstraints { make in
make.bottom.right.equalToSuperview().offset(-12)
make.height.width.equalTo(24)
}
self.extensionView.snp.makeConstraints { make in
make.center.equalTo(self.selectImageView.snp.center)
make.height.width.equalTo(80)
}
}
required init?(coder: NSCoder) {
......@@ -231,89 +162,9 @@ class CompressSelectCell : UICollectionViewCell {
}
@objc func imageClick(){
if self.currentMediaType == .compressPhoto {
// 点击之后跳转详情页面
if let tempModel = self.model {
let vc = PMShowImgVideoController()
vc.state = .similarPhotos
vc.currentIdx = 0
vc.oldPageIndexPath = indexPath
let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = self.choose
dataSource.id = tempModel
// 获取image
dataSource.image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: tempModel.localIdentifier)
vc.homeDataSource = [dataSource]
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
if let data = data{
if let item = data.first{
self.choose = item.isSeleted ?? false
}
}
}
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
}
}else{
// 如果是视频
if let tempModel = self.model {
// 获取视频的图片
PhotoAndVideoMananger.mananger.getVideoImageByIdent(ident: tempModel) { image in
// 点击之后跳转详情页面
let vc = PMShowImgVideoController()
vc.state = .similarVideos
vc.currentIdx = 0
vc.oldPageIndexPath = self.indexPath
let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = self.choose
dataSource.id = tempModel
dataSource.image = image
// 表示这个是视频
vc.homeDataSource = [dataSource]
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
if let data = data{
if let item = data.first{
self.choose = item.isSeleted ?? false
}
}
}
vc.getVideoURLFromLocalIdentifier(localIdentifier: tempModel.localIdentifier) { url, error in
if url != nil{
DispatchQueue.main.async {
vc.url = url
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
}
}else{
let alert = UIAlertController(title: nil, message: "ICloud video cannot be viewed", preferredStyle: .alert)
self.responderViewController()?.present(alert, animated: true, completion: nil)
// 2 秒后关闭弹窗
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
}
}
}
} errorHandler: {
DispatchQueue.main.async {
let alert = UIAlertController(title: nil, message: "Get Video image failure", preferredStyle: .alert)
self.responderViewController()?.navigationController?.present(alert, animated: true)
// 1秒之后消失
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
self.responderViewController()?.navigationController?.popViewController(animated: true)
}
}
}
}
}
}
// @objc func imageClick(){
//
//
// }
}
......@@ -11,79 +11,105 @@ import Lottie
class CompressCompletedViewController : BaseViewController{
var model : [AssetModel]?
// MARK: 属性
var model : AssetModel?
var comDataSource : [Data] = []
var comDataSource : [Data] = [] {
didSet{
if let data = comDataSource.first{
DispatchQueue.main.async {
self.preImageView.image = UIImage(data: data)
self.infoView.isHidden = true
}
}
}
}
var comVideoDataSource : [URL?] = []
var comVideoDataSource : [URL] = []{
didSet{
if let url = comVideoDataSource.first{
DispatchQueue.main.async {
self.infoView.playVideo(from: url)
self.preImageView.isHidden = true
}
}
}
}
var currentMediaType : CompressType = .compressPhoto
var currentMediaType : CompressType = .compressPhoto {
didSet{
if currentMediaType == .compressPhoto {
self.deleteButton.setTitle("Delete the original photo", for: .normal)
self.keepButton.setTitle("Keep two photos", for: .normal)
}else {
self.deleteButton.setTitle("Delete the original video", for: .normal)
self.keepButton.setTitle("Keep two videos", for: .normal)
}
}
}
lazy var bacView : UIView = {
let view = UIView()
view.layer.cornerRadius = 115
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
return view
}()
var completedSize : Double = 0.0 {
didSet{
DispatchQueue.main.async {
if let model = self.model {
self.sizeToplabel.text = formatFileSize(model.assetSize - self.completedSize)
}
}
}
}
lazy var animationView : LottieAnimationView = {
let animationView = LottieAnimationView(name: "iOS压缩完成")
animationView.layer.cornerRadius = 12
animationView.backgroundColor = .clear
animationView.loopMode = .loop
return animationView
}()
// MARK: 懒加载
lazy var topImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "Group")
return view
}()
lazy var tipLabel: UILabel = {
let label = UILabel()
label.text = "Congratulations!"
label.textAlignment = .center
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 20, weight: .bold)
label.font = UIFont.systemFont(ofSize: 20, weight: .semibold)
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "You've cleaned your phone"
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.text = "Preview"
label.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
label.backgroundColor = .clear
return label
}()
lazy var infoView: UIView = {
let view = UIView()
lazy var infoView: SecretVideoPlayer = {
let view = SecretVideoPlayer()
view.backgroundColor = .white
view.clipsToBounds = true
view.layer.cornerRadius = 12
return view
}()
lazy var topImageView: UIImageView = {
lazy var preImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_compressed_end")
view.layer.cornerRadius = 12
view.contentMode = .scaleAspectFit
view.clipsToBounds = true
return view
}()
lazy var tipTopLabel: UILabel = {
let label = UILabel()
label.text = "Compressed"
label.textAlignment = .left
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTipToplabel: UILabel = {
lazy var tipTopLabel: UILabel = {
let label = UILabel()
label.text = "2 items"
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.text = "You have saved a total after compression"
label.textAlignment = .center
label.textColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .medium)
label.backgroundColor = .clear
return label
}()
......@@ -91,261 +117,178 @@ class CompressCompletedViewController : BaseViewController{
let label = UILabel()
label.text = "511MB"
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.textAlignment = .right
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.layer.borderColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 20, weight: .medium)
label.backgroundColor = .clear
return label
}()
lazy var bottomImageView: UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_freed_end")
lazy var keepButton : UIButton = {
let view = UIButton()
view.setTitle("Keep two videos", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
view.clipsToBounds = true
view.layer.cornerRadius = 25.5
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
view.addTarget(self, action: #selector(keepButtonAction), for: .touchUpInside)
return view
}()
lazy var tipBottomLabel: UILabel = {
let label = UILabel()
label.text = "Compressed"
label.textAlignment = .left
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
label.backgroundColor = .clear
return label
}()
lazy var detailTipBottomlabel: UILabel = {
let label = UILabel()
label.text = "2 items"
label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var sizeBottomlabel: UILabel = {
let label = UILabel()
label.text = "1.0%"
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.textAlignment = .right
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.layer.borderColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
label.backgroundColor = .clear
return label
}()
lazy var finalTipLabel: UILabel = {
let label = UILabel()
label.text = "To free up storage permanently or recover media, go to the“Recently Deleted“ album on your device."
label.textColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1)
label.textAlignment = .center
label.numberOfLines = 0
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var completedButton : UIButton = {
lazy var deleteButton : UIButton = {
let view = UIButton()
view.setTitle("Compress", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.setTitle("Delete the original photo", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1), for: .normal)
view.clipsToBounds = true
view.layer.cornerRadius = 23
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
view.addTarget(self, action: #selector(completedAction), for: .touchUpInside)
view.layer.cornerRadius = 25.5
view.backgroundColor = .clear
view.addTarget(self, action: #selector(deleteButtonAction), for: .touchUpInside)
return view
}()
func setUI(){
// MARK: 系统方法
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.titleView.isHidden = true
self.view.addSubview(self.bacView)
self.view.addSubview(self.animationView)
self.setUI()
}
// MARK: 设置UI
func setUI(){
self.view.addSubview(self.topImageView)
self.view.addSubview(self.tipLabel)
self.view.addSubview(self.detailTiplabel)
self.view.addSubview(self.infoView)
self.infoView.addSubview(self.topImageView)
self.infoView.addSubview(self.tipTopLabel)
self.infoView.addSubview(self.detailTipToplabel)
self.infoView.addSubview(self.sizeToplabel)
self.infoView.addSubview(self.bottomImageView)
self.infoView.addSubview(self.tipBottomLabel)
self.infoView.addSubview(self.detailTipBottomlabel)
self.infoView.addSubview(self.sizeBottomlabel)
self.infoView.addSubview(self.finalTipLabel)
self.view.addSubview(self.completedButton)
self.view.addSubview(self.preImageView)
self.view.addSubview(self.tipTopLabel)
self.view.addSubview(self.sizeToplabel)
self.view.addSubview(self.keepButton)
self.view.addSubview(self.deleteButton)
self.bacView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230)
make.centerX.equalToSuperview()
}
self.animationView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230)
self.topImageView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 19)
make.width.height.equalTo(55)
make.centerX.equalToSuperview()
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalTo(self.animationView.snp.bottom).offset(24)
make.width.equalTo(295)
make.top.equalTo(self.topImageView.snp.bottom).offset(12)
make.width.equalTo(159)
make.height.equalTo(28)
make.centerX.equalToSuperview()
}
self.detailTiplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipLabel.snp.bottom).offset(4)
make.width.equalTo(295)
make.width.equalTo(159)
make.height.equalTo(22)
make.centerX.equalToSuperview()
}
self.infoView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(40)
make.width.equalTo(345)
make.height.equalTo(184)
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(14)
make.width.equalTo(244)
make.height.equalTo(316)
make.centerX.equalToSuperview()
}
self.topImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(24)
make.width.height.equalTo(32)
self.preImageView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(14)
make.width.equalTo(244)
make.height.equalTo(316)
make.centerX.equalToSuperview()
}
self.tipTopLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.width.equalTo(120)
make.top.equalTo(self.preImageView.snp.bottom).offset(32)
make.width.equalTo(333)
make.height.equalTo(22)
make.left.equalTo(self.topImageView.snp.right).offset(8)
}
self.detailTipToplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipTopLabel.snp.bottom).offset(0)
make.width.equalTo(120)
make.height.equalTo(17)
make.left.equalTo(self.topImageView.snp.right).offset(8)
make.centerX.equalToSuperview()
}
self.sizeToplabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(26)
make.left.equalTo(self.detailTipToplabel.snp.right).offset(5)
make.height.equalTo(28)
make.right.equalToSuperview().offset(-20)
}
self.bottomImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(79)
make.width.height.equalTo(32)
}
self.tipBottomLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(75)
make.width.equalTo(120)
make.height.equalTo(22)
make.left.equalTo(self.bottomImageView.snp.right).offset(8)
}
self.detailTipBottomlabel.snp.makeConstraints { make in
make.top.equalTo(self.tipBottomLabel.snp.bottom).offset(0)
make.width.equalTo(120)
make.height.equalTo(17)
make.left.equalTo(self.bottomImageView.snp.right).offset(8)
}
self.sizeBottomlabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(81)
make.left.equalTo(self.detailTipBottomlabel.snp.right).offset(5)
make.top.equalTo(self.tipTopLabel.snp.bottom).offset(4)
make.width.equalTo(333)
make.height.equalTo(28)
make.right.equalToSuperview().offset(-20)
make.centerX.equalToSuperview()
}
self.finalTipLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(34)
make.bottom.equalToSuperview().offset(-20)
self.keepButton.snp.makeConstraints { make in
make.bottom.equalToSuperview().offset(-safeHeight - 78)
make.height.equalTo(51)
make.width.equalTo(304)
make.centerX.equalToSuperview()
}
self.completedButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
make.bottom.equalToSuperview().offset(-24)
self.deleteButton.snp.makeConstraints { make in
make.bottom.equalToSuperview().offset(-safeHeight - 27)
make.height.equalTo(51)
make.width.equalTo(304)
make.centerX.equalToSuperview()
}
}
@objc func completedAction(){
// MARK: 事件方法
/// 保留两个
@objc func keepButtonAction(){
if currentMediaType == .compressPhoto {
// 将压缩后的照片存到相册
for imageData in self.comDataSource {
if let imageData = self.comDataSource.first {
PHPhotoLibrary.shared().performChanges({
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, data: imageData, options: nil)
}) { success, error in
if(success){
print("保存照片成功")
}else {
if let error = error {
print("保存相片时出错: \(error.localizedDescription)")
}
}
self.showDeleteSuccess(fileCount: 1, fileSize: Int64(self.completedSize))
}
}else {
self.showDeleteSuccess(fileCount: 1, fileSize: Int64(self.completedSize))
}
}else{
for item in self.comVideoDataSource {
guard let item else {
print("保存视频失败,URL为空")
self.jumpToCompressVC()
return
// 保存视频到相册
PHPhotoLibrary.shared().performChanges({
if let url = self.comVideoDataSource.first{
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url as URL)
}
// 保存视频到相册
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: item as URL)
}) { (success, saveError) in
if success {
print("保存视频成功")
}else{
if let error = saveError {
print("保存视频时出错: \(error.localizedDescription)")
}
}) { (success, saveError) in
if success {
print("保存视频成功")
}else{
if let error = saveError {
print("保存视频时出错: \(error.localizedDescription)")
}
}
self.showDeleteSuccess(fileCount: 1, fileSize: Int64(self.completedSize))
}
}
// 删除文件逻辑【系统自动提示是否删除】
var idents :[String] = []
for ele in self.model! {
idents.append(ele.localIdentifier)
}
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: idents, options: nil)
let fileSize = FileTool().calculateTotalAssetSize(fetchResult: fetchResult)
let assetToDelete = fetchResult.firstObject
PHPhotoLibrary.shared().performChanges ({
PHAssetChangeRequest.deleteAssets([assetToDelete] as NSFastEnumeration)
}){ success, error in
var models :[AssetModel] = []
var count = 0
for ele in self.model! {
count = count + 1
self.updateCompressData(flag: ele.localIdentifier)
let deleteModel = AssetModel(localIdentifier: ele.localIdentifier, assetSize: ele.assetSize, createDate: ele.createDate)
models.append(deleteModel)
}
if(success){
// PhotoDataManager.manager.removeDataWhenDeleteInPage(data: models)
PhotoManager.shared.removeDataWhenDeleteInPage(data: models)
print("删除文件成功")
self.showDeleteSuccess(fileCount:count, fileSize: fileSize)
}else {
if let error = error {
print("删除文件时出错: \(error.localizedDescription)")
}
/// 删除原数据
@objc func deleteButtonAction(){
if let model = self.model {
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [model.localIdentifier], options: nil)
PHPhotoLibrary.shared().performChanges ({
PHAssetChangeRequest.deleteAssets(fetchResult as NSFastEnumeration)
}){ success, error in
if(success){
PhotoManager.shared.removeDataWhenDeleteInPage(data: [self.model!])
print("删除文件成功")
}
self.showDeleteSuccess(fileCount:count, fileSize: fileSize)
self.showDeleteSuccess(fileCount: 1, fileSize: Int64(self.completedSize))
}
}else {
self.showDeleteSuccess(fileCount: 1, fileSize: Int64(self.completedSize))
}
}
// MARK: 辅助方法
// 删除成功页面
func showDeleteSuccess(fileCount:Int,fileSize:Int64){
DispatchQueue.main.async {
self.jumpToCompressVC()
self.jumpToRootVC()
let vc = DelSuccessViewController()
vc.delType = fileCount > 1 ? "photos" : "photo"
vc.fileSzie = fileSize
......@@ -355,31 +298,13 @@ class CompressCompletedViewController : BaseViewController{
}
}
func jumpToCompressVC(){
/// 返回压缩控制器
func jumpToRootVC(){
DispatchQueue.main.async {
if let targetVC = self.navigationController?.viewControllers.first(where: { $0 is CompressController }) {
self.navigationController?.popToViewController(targetVC, animated: true)
}
}
}
/// 更新数据
/// - Parameter flag: 图片的ident
func updateCompressData(flag : String){
DispatchQueue.main.async {
// 移除VC中的数据
let compressVC = self.navigationController?.viewControllers.first(where: { $0 is CompressController }) as! CompressController as CompressController
compressVC.resourceData.removeAll { $0.localIdentifier == flag }
}
}
override func viewDidLoad() {
super.viewDidLoad()
setUI()
self.animationView.play(fromProgress: 0, toProgress: 1,loopMode: .loop)
}
}
......@@ -21,11 +21,7 @@ class CompressController : BaseViewController {
private var compressNav:CompressNavView?
// 排序
var currentSort : ResouceSortType = .largest {
didSet{
clearSelected()
}
}
var currentSort : ResouceSortType = .largest
// 资源类型 - 相册或者视频
var currentResourceType : CompressType = .compressPhoto
......@@ -39,15 +35,12 @@ class CompressController : BaseViewController {
}
}
// 当前页面选中的
var selectedModel : [AssetModel] = []
lazy var collectionView:UICollectionView = {
let layout = WaterfallMutiSectionFlowLayout()
layout.delegate = self
let sview:UICollectionView = UICollectionView.init(frame: CGRect(x: marginLR, y: self.compressNav!.height, width: self.view.width - 2 * marginLR, height: self.view.height - self.compressNav!.height - 102), collectionViewLayout: layout)
let sview:UICollectionView = UICollectionView.init(frame: CGRect(x: marginLR, y: self.compressNav!.height, width: self.view.width - 2 * marginLR, height: self.view.height - self.compressNav!.height), collectionViewLayout: layout)
sview.register(CompressSelectCell.self, forCellWithReuseIdentifier: "CompressSelectCell")
sview.register(CompressCustomHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CompressCustomHeaderView")
sview.register( UICollectionReusableView.self,forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter,withReuseIdentifier: "footerID")
......@@ -64,18 +57,6 @@ class CompressController : BaseViewController {
}()
lazy var submitButton : UIButton = {
let view = UIButton()
view.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
view.setTitle("Compress", for: UIControl.State.normal)
view.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.clipsToBounds = true
view.layer.cornerRadius = 23
view.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
view.addTarget(self, action: #selector(startCompress), for: .touchUpInside)
return view
}()
func setUI(){
compressNav = CompressNavView(frame: CGRect(x: 0, y: 0, width: self.view.width, height: statusBarHeight + 44))
......@@ -85,18 +66,7 @@ class CompressController : BaseViewController {
make.top.centerX.width.equalToSuperview()
make.height.equalTo(statusBarHeight + 44)
})
self.view.insertSubview(collectionView, at: 0)
self.view.addSubview(self.submitButton)
self.submitButton.snp.makeConstraints { make in
make.top.equalTo(self.collectionView.snp.bottom).offset(16)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
}
}
override func viewDidLoad() {
......@@ -126,11 +96,6 @@ class CompressController : BaseViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// 目的是为了消除cell 的选择按钮状态
if self.selectedModel.count == 0 {
self.collectionView.reloadData()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
......@@ -157,28 +122,6 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
cell.currentMediaType = self.currentResourceType
cell.model = self.resourceData[indexPath.row]
cell.indexPath = indexPath
if self.selectedModel.count == 0 {
cell.choose = false
}
cell.callBack = {[weak self] (model:AssetModel,choose:Bool) ->() in
guard let self else{ return}
// 这里临时管理一个当前选择的资源
if choose == true && !self.selectedModel.contains(model) {
self.selectedModel.append(model)
self.vibrate()
}
if choose == false && self.selectedModel.contains(model){
self.vibrate()
if let index = selectedModel.firstIndex(of: model) {
selectedModel.remove(at: index)
}
}
DispatchQueue.main.async {
// 选择完成后检查选择的是否有值,有值则变换底部的按钮
self.updateSubmitButton()
}
}
return cell
}
......@@ -211,7 +154,35 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if self.currentResourceType == .compressPhoto{
// 判断资源是否存在
let options = PHImageRequestOptions()
options.isNetworkAccessAllowed = false
options.progressHandler = nil
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [self.resourceData[indexPath.row].localIdentifier], options: nil)
guard let phAsset = fetchResult.firstObject else {
showAlert()
return
}
PHImageManager.default().requestImageDataAndOrientation(
for: phAsset,
options: options
) { data, _, _, info in
if data == nil {
self.showAlert()
}else {
self.startCompress(model: self.resourceData[indexPath.row])
}
}
}else {
self.getVideoURLFromLocalIdentifier(localIdentifier: self.resourceData[indexPath.row].localIdentifier) { url, error in
if url != nil {
self.startCompress(model: self.resourceData[indexPath.row])
}else {
self.showAlert()
}
}
}
}
func referenceSizeForHeader(collectionView collection: UICollectionView, layout: WaterfallMutiSectionFlowLayout, section: Int) -> CGSize {
......@@ -236,7 +207,6 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
if self.currentResourceType != flag {
self.currentResourceType = flag
// 先移除下,防止点到
self.selectedModel.removeAll()
self.resourceData.removeAll()
// 如果是图片,直接从缓存中加载
if self.currentResourceType == .compressPhoto {
......@@ -290,29 +260,8 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
}
}
func updateSubmitButton(){
if self.selectedModel.count > 0 {
self.submitButton.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
if self.currentResourceType == .compressPhoto {
self.submitButton.setTitle("Compress \(self.selectedModel.count) photos", for: UIControl.State.normal)
}else{
self.submitButton.setTitle("Compress \(self.selectedModel.count) videos", for: UIControl.State.normal)
}
self.submitButton.setTitleColor(.white, for: .normal)
}else{
self.submitButton.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
self.submitButton.setTitle("Compress", for: UIControl.State.normal)
self.submitButton.setTitleColor(UIColor(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
}
}
@objc func startCompress(){
func startCompress(model:AssetModel){
// 如果没有不进行下一步操作
if self.selectedModel.count == 0 {
return
}
if IAPManager.share.isSubscribed == false {
HomePayViewController.show {
if IAPManager.share.isSubscribed == false{
......@@ -327,21 +276,22 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
self.present(alertView, animated: true)
alertView.selectClickCallback = {isSure in
self.view.hideBlur()
alertView.dismiss(animated: true)
if isSure {
self.popAdverTisement()
AdvManager.shared.finisedCallBack = {
self.jumpToNextPage()
alertView.dismiss(animated: true) {
if isSure {
self.popAdverTisement()
AdvManager.shared.finisedCallBack = {
self.jumpToNextPage(model: model)
}
}
}
}
}else {
self.jumpToNextPage()
self.jumpToNextPage(model: model)
}
}
}else {
self.jumpToNextPage()
self.jumpToNextPage(model: model)
}
}
......@@ -350,27 +300,60 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
AdvManager.shared.showInterstitialAd(vc: self)
}
func jumpToNextPage(){
func jumpToNextPage(model:AssetModel){
// 先将值传到下一个页面
let vc : CompressQualityController = CompressQualityController()
vc.currentMediaType = self.currentResourceType
vc.model = self.selectedModel
if self.currentResourceType == .compressPhoto{
vc.detailTiplabel.text = "You've selected \(self.selectedModel.count) photos(A total of \(self.resourceData.count)) to compress."
}else{
vc.detailTiplabel.text = "You've selected \(self.selectedModel.count) videos(A total of \(self.resourceData.count)) to compress."
}
vc.model = model
self.navigationController?.pushViewController(vc, animated: true)
// 然后清理下当前页面的值
clearSelected()
}
func showAlert(){
let alert = UIAlertController(title: nil, message: "ICloud video cannot be viewed", preferredStyle: .alert)
self.present(alert, animated: true, completion: nil)
// 2 秒后关闭弹窗
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
}
}
func clearSelected() {
self.selectedModel.removeAll()
self.updateSubmitButton()
// 注意私有方法(某些参数不一样) 这个只能在这个类中使用
private func getVideoURLFromLocalIdentifier(localIdentifier: String, completion: @escaping (URL?, Error?) -> Void) {
// 通过 localIdentifier 获取 PHAsset
let fetchOptions = PHFetchOptions()
let assets = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: fetchOptions)
guard let asset = assets.firstObject, asset.mediaType == .video else {
DispatchQueue.main.async {
completion(nil, NSError(domain: "com.example.error", code: 1, userInfo: [NSLocalizedDescriptionKey: "未找到对应视频资源"]))
}
return
}
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = false // 允许从网络下载
options.deliveryMode = .fastFormat // 要求高质量格式
PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { (avAsset, audioMix, info) in
if let error = info?[PHImageErrorKey] as? Error {
DispatchQueue.main.async {
completion(nil, error)
}
return
}
if let urlAsset = avAsset as? AVURLAsset {
DispatchQueue.main.async {
completion(urlAsset.url, nil)
}
} else {
DispatchQueue.main.async {
completion(nil, NSError(domain: "CustomErrorDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to get video URL"]))
}
}
}
}
......
......@@ -9,40 +9,21 @@ import Foundation
/// 压缩多少枚举
enum CompressQualityType {
enum CompressQualityType : Double {
// 压缩少量
case low
case low = 0.8
// 压缩中等
case mid
case mid = 0.5
// 压缩较多
case high
case high = 0.2
}
class CompressQualityController : BaseViewController{
var model : [AssetModel]? {
didSet{
if let model = model {
if let modelFirst = model.first {
if self.currentMediaType == .compressPhoto {
let ident = modelFirst.localIdentifier
let image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: ident)
self.imageView.image = image
}else {
// 获取视频的URL
PhotoAndVideoMananger.mananger.getVideoURLFromLocalIdentifier(localIdentifier: modelFirst.localIdentifier) { url, error in
if let url = url {
self.videoView.videoUrl = url
}
}
}
}
}
}
}
var model : AssetModel?
var currentQulityType : Int = 0
var currentQulityType : CompressQualityType = .low
var currentMediaType : CompressType = .compressPhoto {
didSet{
......@@ -59,19 +40,17 @@ class CompressQualityController : BaseViewController{
let view = VideoPlayView()
view.clipsToBounds = true
view.layer.cornerRadius = 12
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.backgroundColor = .clear
return view
}()
lazy var imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.layer.cornerRadius = 12
imageView.contentMode = .scaleAspectFill
imageView.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
imageView.contentMode = .scaleAspectFit
imageView.backgroundColor = .clear
imageView.image = UIImage(named: "img_compress")
return imageView
}()
......@@ -84,15 +63,6 @@ class CompressQualityController : BaseViewController{
label.backgroundColor = .clear
return label
}()
lazy var detailTiplabel: UILabel = {
let label = UILabel()
label.text = "You've selected 2 photos(A total of 17) to compress."
label.textAlignment = .left
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.backgroundColor = .clear
return label
}()
lazy var lowQualityView: QualityView = {
let view = QualityView()
view.type = 0
......@@ -148,7 +118,6 @@ class CompressQualityController : BaseViewController{
self.view.addSubview(self.videoView)
self.view.addSubview(self.imageView)
self.view.addSubview(self.tipLabel)
self.view.addSubview(self.detailTiplabel)
self.view.addSubview(self.lowQualityView)
self.view.addSubview(self.mediumQualityView)
self.view.addSubview(self.highQualityView)
......@@ -159,29 +128,23 @@ class CompressQualityController : BaseViewController{
make.top.equalTo(self.compressNav!.height + 20)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(259)
make.height.equalTo(267 * ((self.view.width - 30) / 345))
}
self.videoView.snp.makeConstraints { make in
make.top.equalTo(self.compressNav!.height + 20)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(259)
make.height.equalTo(267 * ((self.view.width - 30) / 345))
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalTo(self.imageView.snp.bottom).offset(28)
make.top.equalTo(self.imageView.snp.bottom).offset(20)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(22)
}
self.detailTiplabel.snp.makeConstraints { make in
make.top.equalTo(self.tipLabel.snp.bottom).offset(4)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(17)
}
self.lowQualityView.snp.makeConstraints { make in
make.top.equalTo(self.detailTiplabel.snp.bottom).offset(16)
make.top.equalTo(self.tipLabel.snp.bottom).offset(16)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(61)
......@@ -226,7 +189,7 @@ class CompressQualityController : BaseViewController{
self.lowQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 0
self.currentQulityType = .low
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.lowQualityView.layer.borderWidth = 1
self.mediumQualityView.layer.borderWidth = 0
......@@ -234,12 +197,13 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
setButtonTitleByType(type: .low)
setImageByType(type: .low)
self.vibrate()
}
self.mediumQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 1
self.currentQulityType = .mid
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.lowQualityView.layer.borderWidth = 0
self.mediumQualityView.layer.borderWidth = 1
......@@ -247,12 +211,13 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
setButtonTitleByType(type: .mid)
setImageByType(type: .mid)
self.vibrate()
}
self.highQualityView.callBack = {[weak self] type in
guard let self else {return}
self.currentQulityType = 2
self.currentQulityType = .high
self.lowQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.lowQualityView.layer.borderWidth = 0
self.mediumQualityView.layer.borderWidth = 0
......@@ -260,35 +225,40 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
setButtonTitleByType(type: .high)
setImageByType(type: .high)
self.vibrate()
}
// 设置默认值
setButtonTitleByType(type: .low)
setImageByType(type: .low)
}
func setButtonTitleByType(type : CompressQualityType){
var size : Double = 0.0
if let array = self.model{
for item in array {
size = size + item.assetSize
}
}
// 求和之后看点击的是哪个
var compressSize : Double = 0.0
let size : Double = model?.assetSize ?? 0.0
let compressSize : Double = size * (1 - type.rawValue)
// 设置按钮内容将要压缩的大小
self.submitButton.setTitle("Compress \(formatFileSize(compressSize))", for: .normal)
}
func setImageByType(type : CompressQualityType){
if type == .low {
compressSize = size * 0.2
self.imageView.image = UIImage(named: "img_compress")
self.videoView.videoView.image = UIImage(named: "img_compress 3")
}else if type == .mid {
compressSize = size * 0.5
self.imageView.image = UIImage(named: "img_compress 1")
self.videoView.videoView.image = UIImage(named: "img_compress 4")
}else {
compressSize = size * 0.8
self.imageView.image = UIImage(named: "img_compress 2")
self.videoView.videoView.image = UIImage(named: "img_compress 5")
}
self.submitButton.setTitle("Compress \(formatFileSize(compressSize))", for: .normal)
}
fileprivate func updateNextView(_ compressAllSize: Double, _ compressingView: CompressingView,_ comDataSource : [Data],_ comVideoDataSource : [URL?]) {
fileprivate func updateNextView(_ compressAllSize: Double, _ compressingView: CompressingView,_ comDataSource : [Data],_ comVideoDataSource : [URL]) {
DispatchQueue.main.async {
compressingView.removeFromSuperview()
let vc = CompressCompletedViewController()
......@@ -296,101 +266,17 @@ class CompressQualityController : BaseViewController{
vc.comDataSource = comDataSource
vc.comVideoDataSource = comVideoDataSource
vc.model = self.model
vc.detailTipToplabel.text = "\(self.model!.count) items"
vc.detailTipBottomlabel.text = "\(self.model!.count) items"
var sum = 0.0
var orgAllSize = 0.0
for modelData in self.model! {
orgAllSize = orgAllSize + modelData.assetSize
}
sum = orgAllSize - compressAllSize
sum = sum / 1000
if sum < 1000{
vc.sizeToplabel.text = String(format:"%.2lfKB",sum)
}else if sum < (1000 * 1000) && sum > 1000{
sum = sum / 1000
vc.sizeToplabel.text = String(format:"%.2lfMB",sum)
}else{
sum = sum / (1000 * 1000)
vc.sizeToplabel.text = String(format:"%.2lfGB",sum)
}
let str = String(format:"%.2lf",(orgAllSize - compressAllSize) / orgAllSize)
vc.sizeBottomlabel.text = "\(str)%"
self.navigationController?.pushViewController(vc, animated: true)
}
}
@objc func submitAction(){
let actionBlock = { [weak self] in
guard let self = self else { return }
let compressingView : CompressingView = CompressingView(frame: self.view.bounds)
compressingView.data = self.model
self.view.addSubview(compressingView)
// 开始压缩
let manager : CompressViewModel = CompressViewModel()
var currentQulity = 0.2
if currentQulityType == 1 {
currentQulity = 0.5
}
if currentQulityType == 2 {
currentQulity = 0.8
}
var comDataSource : [Data] = []
if self.currentMediaType == .compressPhoto {
// 表示压缩图片
manager.compress(assets: self.model!, compressionQuality: currentQulity) {progress in
compressingView.animationView.setProgress(CGFloat(progress), animated: false, duration: 0.1)
} completion: { compressedDataArray, errorArray in
var compressAllSize = 0.0
for (index, data) in compressedDataArray.enumerated() {
if let error = errorArray[index] {
print("第 \(index + 1) 个文件压缩出错: \(error.localizedDescription)")
} else if let data = data {
print("第 \(index + 1) 个文件压缩完成,压缩后大小: \(data.count) 字节")
compressAllSize = compressAllSize + Double(data.count)
comDataSource.append(data)
} else {
print("第 \(index + 1) 个文件压缩失败")
}
}
self.updateNextView(compressAllSize,compressingView,comDataSource,[])
}
}else{
// 压缩视频
var compressAllSize : Double = 0.0
CompressViewModel.compressVideos(models: self.model!, quality: Float(currentQulity)) { progress in
compressingView.animationView.setProgress(CGFloat(progress), animated: false, duration: 0.1)
} completion: { (outputURLs, errors) in
for (index, outputURL) in outputURLs.enumerated() {
if let outputURL = outputURL {
do {
let attributes = try FileManager.default.attributesOfItem(atPath: outputURL.path)
if let fileSize = attributes[.size] as? Int64 {
compressAllSize = compressAllSize + Double(fileSize)
}
} catch {
Print("获取视频文件大小失败")
}
} else if let error = errors[index] {
print("Error compressing video \(index): \(error.localizedDescription)")
}
}
Print("---------压缩后的大小:\(compressAllSize)")
// 不管成功失败都跳转下一页
self.updateNextView(compressAllSize,compressingView,[],outputURLs)
}
}
}
actionBlock()
// 跳转进度页面
let vc : CompressingViewController = CompressingViewController()
vc.model = self.model
vc.qualityType = self.currentQulityType
vc.currentMediaType = self.currentMediaType
self.navigationController?.pushViewController(vc, animated: true)
}
}
//
// CompressingViewController.swift
// PhoneManager
//
// Created by edy on 2025/5/21.
//
import UIKit
import Lottie
class CompressingViewController: BaseViewController {
var currentMediaType : CompressType = .compressPhoto
var model : AssetModel? {
didSet{
if let model = model {
DispatchQueue.main.async {
self.orgSizeLabel.text = formatFileSize(model.assetSize)
}
}
}
}
var qualityType : CompressQualityType = .low {
didSet{
if let model = model {
DispatchQueue.main.async {
self.targetSizeLabel.text = formatFileSize(model.assetSize * self.qualityType.rawValue)
}
}
}
}
lazy var bacImageView : UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "Group_1171275114")
return view
}()
lazy var animationViewBacView : UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "* 白色实心圆-小")
view.backgroundColor = .clear
return view
}()
lazy var animationView : LottieAnimationView = {
let animationView = LottieAnimationView(name: "iOS压缩完成")
animationView.layer.cornerRadius = 12
animationView.backgroundColor = .clear
animationView.loopMode = .loop
return animationView
}()
lazy var tipLabel : UILabel = {
let label = UILabel()
label.text = "We're freeing up space on your device!"
label.textColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
label.font = UIFont.systemFont(ofSize: 18, weight: .medium)
label.textAlignment = .center
label.numberOfLines = 0
return label
}()
lazy var orgSizeLabel : UILabel = {
let label = UILabel()
label.textColor = UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .medium)
label.textAlignment = .left
return label
}()
lazy var targetSizeLabel : UILabel = {
let label = UILabel()
label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .medium)
label.textAlignment = .right
return label
}()
lazy var progressBar : CustomCompressProgressBar = {
let bar = CustomCompressProgressBar()
bar.thumbImage = UIImage(named: "Group_1171275116")
bar.layer.cornerRadius = 3.5
bar.clipsToBounds = true
return bar
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.titleView.isHidden = true
setUI()
startCompress()
}
// MARK: 压缩方法
/// 开始压缩
func startCompress(){
if self.currentMediaType == .compressPhoto {
self.compressPhoto(model: self.model)
}else {
self.compressVideo(model: self.model)
}
}
/// 压缩单个图片
/// - Parameter model: 资源
private func compressPhoto(model : AssetModel?){
if let model = model {
var comDataSource : [Data] = []
let manager : CompressViewModel = CompressViewModel()
manager.compress(assets: [model], compressionQuality: qualityType.rawValue) {progress in
DispatchQueue.main.async {
self.progressBar.updateProgress(to: CGFloat(progress))
}
} completion: { compressedDataArray, errorArray in
var compressAllSize = 0.0
for (_, data) in compressedDataArray.enumerated() {
if let data = data {
compressAllSize = compressAllSize + Double(data.count)
comDataSource.append(data)
}
}
self.progressBar.animationCompletion = {
// 不管成功失败都跳转下一页
self.updateNextView(compressAllSize,comDataSource,[])
}
}
}
}
/// 压缩单个视频
/// - Parameter model: 资源
private func compressVideo(model : AssetModel?){
if let model = model {
var compressAllSize : Double = 0.0
CompressViewModel.compressVideos(models: [model], quality: Float(qualityType.rawValue)) { progress in
DispatchQueue.main.async {
self.progressBar.updateProgress(to: CGFloat(progress))
}
} completion: { (outputURLs, errors) in
var finallyUrls : [URL] = []
for (_, outputURL) in outputURLs.enumerated() {
if let outputURL = outputURL {
do {
let attributes = try FileManager.default.attributesOfItem(atPath: outputURL.path)
if let fileSize = attributes[.size] as? Int64 {
compressAllSize = compressAllSize + Double(fileSize)
}
} catch {
Print("获取视频文件大小失败")
}
finallyUrls.append(outputURL)
}
}
self.progressBar.animationCompletion = {
// 不管成功失败都跳转下一页
self.updateNextView(compressAllSize,[],finallyUrls)
}
}
}
}
/// 压缩结果处理
/// - Parameters:
/// - compressAllSize: 压缩后总大小
/// - comDataSource: 压缩后的图片数据数组
/// - comVideoDataSource: 压缩后的视频链接数组
fileprivate func updateNextView(_ compressAllSize: Double,_ comDataSource : [Data],_ comVideoDataSource : [URL]) {
DispatchQueue.main.async {
let vc = CompressCompletedViewController()
vc.currentMediaType = self.currentMediaType
vc.comDataSource = comDataSource
vc.comVideoDataSource = comVideoDataSource
vc.model = self.model
vc.completedSize = compressAllSize
self.navigationController?.pushViewController(vc, animated: true)
}
}
// MARK: 设置UI
func setUI(){
self.view.addSubview(self.bacImageView)
self.bacImageView.snp.makeConstraints { make in
make.height.equalTo(211)
make.width.equalTo(264.7)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(96 + statusBarHeight)
}
self.view.addSubview(self.animationViewBacView)
self.animationViewBacView.snp.makeConstraints { make in
make.top.equalTo(self.bacImageView.snp.top).offset(58)
make.width.height.equalTo(108.75)
make.centerX.equalToSuperview()
}
self.view.addSubview(self.animationView)
self.animationView.snp.makeConstraints { make in
make.width.height.equalTo(145)
make.top.equalTo(self.bacImageView.snp.top).offset(40)
make.centerX.equalToSuperview()
}
self.view.addSubview(self.tipLabel)
self.tipLabel.snp.makeConstraints { make in
make.width.equalTo(304)
make.height.equalTo(50)
make.centerX.equalToSuperview()
make.top.equalTo(self.bacImageView.snp.bottom).offset(96)
}
self.view.addSubview(self.orgSizeLabel)
self.orgSizeLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.height.equalTo(22)
make.bottom.equalTo(-66 - safeHeight)
}
self.view.addSubview(self.targetSizeLabel)
self.targetSizeLabel.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-16)
make.height.equalTo(22)
make.bottom.equalTo(-66 - safeHeight)
}
self.view.addSubview(self.progressBar)
self.progressBar.snp.makeConstraints { make in
make.left.equalTo(16)
make.right.equalToSuperview().offset(-16)
make.height.equalTo(24)
make.bottom.equalTo(-34 - safeHeight)
}
self.animationView.play(fromProgress: 0, toProgress: 1 , loopMode: .loop)
}
}
......@@ -10,7 +10,7 @@ import Foundation
class CompressingView: UIView{
var data: [AssetModel]?
var data: AssetModel?
override init(frame: CGRect) {
super.init(frame: frame)
......
//
// CustomProgressBar.swift
// PhoneManager
//
// Created by edy on 2025/5/21.
//
import UIKit
class CustomCompressProgressBar: UIView {
var animationCompletion: (() -> Void) = {}
// 背景色(已完成进度颜色)
private let backgroundLayer = CALayer()
// 前景色(已完成进度颜色)
private let foregroundLayer = CALayer()
// 进度指示图标
private let thumbLayer = CALayer()
// 当前进度值(0-1)
private var progress: CGFloat = 0.0
// 动画持续时间
private let animationDuration: CFTimeInterval = 4.0
// 动画定时器
private var displayLink: CADisplayLink?
private var animationStartTime: CFTimeInterval = 0
private var startProgress: CGFloat = 0
private var targetProgress: CGFloat = 0
var thumbImage: UIImage? {
didSet {
thumbLayer.contents = thumbImage?.cgImage
// 调整缩略图锚点
thumbLayer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
// 设置正确尺寸并居中
thumbLayer.frame = CGRect(
x: 0,
y: bounds.height/2 - 12, // 24/2=12
width: 24,
height: 24
)
}
}
// 添加视图配置防止裁剪
override func didMoveToSuperview() {
super.didMoveToSuperview()
self.clipsToBounds = false
layer.masksToBounds = false
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
// 设置背景层
backgroundLayer.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1).cgColor
backgroundLayer.frame = CGRect(x: 0, y: self.bounds.height/2 - 3.5, width: self.bounds.width, height: 7)
backgroundLayer.cornerRadius = 3.5
layer.addSublayer(backgroundLayer)
// 设置前景层
foregroundLayer.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1).cgColor
foregroundLayer.cornerRadius = 3.5
layer.addSublayer(foregroundLayer)
// 设置缩略图层
layer.addSublayer(thumbLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
CATransaction.begin()
CATransaction.setDisableActions(true)
updateLayers(for: progress)
CATransaction.commit()
}
func updateProgress(to newProgress: CGFloat) {
let clampedProgress = max(0, min(newProgress, 1.0))
startProgress = currentPresentationProgress()
targetProgress = clampedProgress
startAnimation()
}
private func currentPresentationProgress() -> CGFloat {
if let presentation = foregroundLayer.presentation() {
return presentation.bounds.width / bounds.width
}
return progress
}
private func startAnimation() {
animationStartTime = CACurrentMediaTime()
displayLink?.invalidate()
displayLink = CADisplayLink(target: self, selector: #selector(updateAnimation))
displayLink?.add(to: .main, forMode: .common)
}
@objc private func updateAnimation() {
let elapsed = CACurrentMediaTime() - animationStartTime
let percent = min(elapsed / animationDuration, 1.0)
let currentProgress = startProgress + (targetProgress - startProgress) * CGFloat(percent)
progress = currentProgress
CATransaction.begin()
CATransaction.setDisableActions(true)
updateLayers(for: currentProgress)
CATransaction.commit()
if percent >= 1.0 {
displayLink?.invalidate()
displayLink = nil
// 触发完成回调
animationCompletion()
}
}
private func updateLayers(for progress: CGFloat) {
let foregroundWidth = bounds.width * progress
foregroundLayer.frame = CGRect(
x: 0,
y: bounds.height/2 - 3.5,
width: foregroundWidth,
height: 7
)
// 修改缩略图位置计算
let thumbSize = thumbLayer.bounds.size
// 计算中心点位置(确保始终显示完整缩略图)
let thumbCenterX = foregroundWidth - thumbSize.width/2
// 限制缩略图显示范围(不超出进度条边界)
let minX = -thumbSize.width/2 // 允许左侧部分超出
let maxX = bounds.width - thumbSize.width/2
thumbLayer.frame.origin.x = max(minX, min(thumbCenterX, maxX))
// 设置垂直居中
thumbLayer.frame.origin.y = bounds.height/2 - thumbSize.height/2
}
}
......@@ -9,15 +9,6 @@ import UIKit
class VideoPlayView: UIView {
var videoUrl : URL? {
didSet {
if let url = videoUrl {
self.videoView.playVideo(from: url)
self.videoView.pause()
}
}
}
lazy var playImageView : UIImageView = {
let imageView = UIImageView()
imageView.backgroundColor = .clear
......@@ -28,18 +19,19 @@ class VideoPlayView: UIView {
lazy var timeLabel : UILabel = {
let label = UILabel()
label.textColor = .white
label.text = "00:00"
label.text = "00:25"
label.font = UIFont.systemFont(ofSize: 14, weight: .semibold)
label.textAlignment = .right
return label
}()
lazy var videoView : SecretVideoPlayer = {
let view = SecretVideoPlayer()
lazy var videoView : UIImageView = {
let view = UIImageView()
view.clipsToBounds = true
view.layer.cornerRadius = 12
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.contentMode = .scaleAspectFit
view.backgroundColor = .clear
return view
}()
......@@ -57,25 +49,6 @@ class VideoPlayView: UIView {
make.top.equalToSuperview().offset(8)
make.height.equalTo(20)
}
self.videoView.callBackCurrtntTimeString = {[weak self]text in
guard let self else {return}
DispatchQueue.main.async {
self.timeLabel.text = text
}
}
self.videoView.tapPauseCallback = {[weak self] state in
guard let self else {return}
if state == .playing {
self.playImageView.isHidden = true
}
if state == .pause {
self.playImageView.isHidden = false
}
if state == .end {
self.playImageView.isHidden = false
self.timeLabel.text = "00:00"
}
}
self.addSubview(self.playImageView)
......
......@@ -136,8 +136,8 @@ class CompressViewModel{
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
// 设置为原图片
options.version = .original
PHImageManager.default().requestImageDataAndOrientation(for: asset, options: options) { (imageData, _, _, error) in
guard let originalData = imageData else {
completion(nil, nil)
......
......@@ -15,8 +15,11 @@ class PayDistanceViewController: UIViewController {
var scrollView:UIScrollView!
var dropImage:UIImageView!
var distanceL:UILabel!
var annual:UILabel!
var cancelLabel:UILabel!
var yearDistacePrice:UILabel!
var offerImage:UIImageView!
var payBtn:UIButton!
......@@ -46,7 +49,7 @@ class PayDistanceViewController: UIViewController {
closeBtn.addTarget(self, action: #selector(payClose), for: .touchUpInside)
scrollView.addSubview(closeBtn)
let offerImage = UIImageView()
offerImage = UIImageView()
offerImage.image = UIImage.init(named: "iap_distance_offer")
scrollView.addSubview(offerImage)
......@@ -56,35 +59,39 @@ class PayDistanceViewController: UIViewController {
scrollView.addSubview(dropImage)
let distanceL = UILabel()
distanceL = UILabel()
distanceL.text = "50% Discount"
distanceL.font = UIFont.systemFont(ofSize: 40, weight: .semibold)
distanceL.textAlignment = .center
distanceL.font = UIFont.systemFont(ofSize: 40.RW(), weight: .semibold)
distanceL.textColor = UIColor.colorWithHex(hexStr: "#111111")
scrollView.addSubview(distanceL)
let annual = UILabel()
annual = UILabel()
annual.text = "Annual visit"
annual.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
annual.textAlignment = .center
annual.font = UIFont.systemFont(ofSize: 18.RW(), weight: .semibold)
annual.textColor = UIColor.colorWithHex(hexStr: "#111111")
scrollView.addSubview(annual)
yearDistacePrice = UILabel()
yearDistacePrice.font = UIFont.systemFont(ofSize: 14,weight: .semibold)
yearDistacePrice.font = UIFont.systemFont(ofSize: 14.RW(),weight: .semibold)
yearDistacePrice.textColor = UIColor.colorWithHex(hexStr: "#111111")
yearDistacePrice.text = ""//"$39.99 $19.99 / Year"
yearDistacePrice.textAlignment = .center
scrollView.addSubview(yearDistacePrice)
let cancelLabel = UILabel()
cancelLabel.font = UIFont.systemFont(ofSize: 12,weight: .semibold)
cancelLabel = UILabel()
cancelLabel.font = UIFont.systemFont(ofSize: 12.RW(),weight: .semibold)
cancelLabel.textColor = UIColor.colorWithHex(hexStr: "#0082FF")
cancelLabel.text = "Cancel at any time"
cancelLabel.textAlignment = .center
scrollView.addSubview(cancelLabel)
payBtn = UIButton()
payBtn.setTitle("Get discounts", for: .normal)
payBtn.setTitleColor(.white, for: .normal)
payBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
payBtn.layer.cornerRadius = 30
payBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18.RW(), weight: .semibold)
payBtn.layer.cornerRadius = 30.RW()
payBtn.isEnabled = false
payBtn.addTarget(self, action: #selector(iapPayAction), for: .touchUpInside)
payBtn.backgroundColor = UIColor.colorWithHex(hexStr: "#0082FF")
......@@ -111,7 +118,7 @@ class PayDistanceViewController: UIViewController {
let appleLabel = UILabel()
appleLabel.font = UIFont.systemFont(ofSize: 10,weight: .medium)
appleLabel.font = UIFont.systemFont(ofSize: 10.RW(),weight: .medium)
appleLabel.textColor = UIColor.colorWithHex(hexStr: "#111111")
appleLabel.text = " Apple Security Guarantee"
scrollView.addSubview(appleLabel)
......@@ -123,18 +130,18 @@ class PayDistanceViewController: UIViewController {
make.size.equalTo(30)
}
offerImage.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(kSafeAreaInsets.top+70)
make.width.equalTo(111)
make.height.equalTo(37)
}
distanceL.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(annual.snp.top).offset(-115.RH())
}
// offerImage.snp.makeConstraints { make in
// make.centerX.equalToSuperview()
// make.top.equalTo(kSafeAreaInsets.top+70)
// make.width.equalTo(111)
// make.height.equalTo(37)
// }
//
// distanceL.snp.makeConstraints { make in
// make.centerX.equalToSuperview()
// make.top.equalTo(annual.snp.top).offset(-115.RH())
// }
//
appleLabel.snp.makeConstraints { make in
......@@ -150,28 +157,28 @@ class PayDistanceViewController: UIViewController {
payBtn.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.equalTo(343)
make.height.equalTo(57)
make.width.equalTo(343.RW())
make.height.equalTo(57.RW())
make.bottom.equalTo(appleLabel.snp.top).offset(-24)
}
cancelLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalTo(payBtn.snp.top).offset(-22)
make.height.equalTo(22)
}
yearDistacePrice.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalTo(cancelLabel.snp.top).offset(0)
make.height.equalTo(22)
}
annual.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalTo(yearDistacePrice.snp.top).offset(-8)
make.height.equalTo(22)
}
// cancelLabel.snp.makeConstraints { make in
// make.centerX.equalToSuperview()
// make.bottom.equalTo(payBtn.snp.top).offset(-22)
// make.height.equalTo(22)
// }
//
// yearDistacePrice.snp.makeConstraints { make in
// make.centerX.equalToSuperview()
// make.bottom.equalTo(cancelLabel.snp.top).offset(0)
// make.height.equalTo(22)
// }
//
// annual.snp.makeConstraints { make in
// make.centerX.equalToSuperview()
// make.bottom.equalTo(yearDistacePrice.snp.top).offset(-8)
// make.height.equalTo(22)
// }
scrollView.addSubview(termsView)
......@@ -218,21 +225,139 @@ class PayDistanceViewController: UIViewController {
let dropW = CGFloat(300.RW())
let dropH = CGFloat(224.RW())
dropImage.frame = CGRect(x: (ScreenW - dropW) / 2, y: -dropH, width: dropW, height: dropH)
// dropImage.frame = CGRect(x: (ScreenW - dropW) / 2, y: -dropH, width: dropW, height: dropH)
//
// offerImage.frame = CGRect(x: (ScreenW - 111) / 2, y: -37, width: 111, height: 37)
// distanceL.frame = CGRect(x: (ScreenW - 270) / 2, y: -40, width: 270, height: 40)
// annual.frame = CGRect(x: (ScreenW - 150) / 2, y: -30, width: 150, height: 22)
// yearDistacePrice.frame = CGRect(x: (ScreenW - 200) / 2, y: -30, width: 200, height: 22)
// cancelLabel.frame = CGRect(x: (ScreenW - 150) / 2, y: -30, width: 150, height: 22)
self.dropImage.frame = CGRect(x: (ScreenW - dropW)/2.0,
y: kSafeAreaInsets.top + 129.RH(), // 根据原来的约束位置计算
width: dropW,
height: dropH)
self.offerImage.frame = CGRect(x: (ScreenW - 111) / 2,
y: kSafeAreaInsets.top + 70,
width: 111,
height: 37)
self.distanceL.frame = CGRect(x: (ScreenW - CGFloat(300.RW())) / 2,
y: kSafeAreaInsets.top + CGFloat(129.RH()) + dropH + CGFloat(40.RH()),
width: CGFloat(300.RW()),
height: CGFloat(40.RW()))
self.annual.frame = CGRect(x: (ScreenW - 150) / 2,
y: self.distanceL.frame.maxY + CGFloat(115.RH()),
width: 150,
height: 22)
self.yearDistacePrice.frame = CGRect(x: (ScreenW - 200) / 2,
y: self.annual.frame.maxY + 8,
width: 200,
height: 22)
self.cancelLabel.frame = CGRect(x: (ScreenW - 200) / 2,
y: self.yearDistacePrice.frame.maxY,
width: 200,
height: 22)
payBtn.alpha = 0
dropImage.alpha = 0
offerImage.alpha = 0
distanceL.alpha = 0
annual.alpha = 0
yearDistacePrice.alpha = 0
cancelLabel.alpha = 0
UIView.animate(withDuration: 1) {
self.payBtn.alpha = 1
self.dropImage.alpha = 1
self.offerImage.alpha = 1
self.distanceL.alpha = 1
self.annual.alpha = 1
self.yearDistacePrice.alpha = 1
self.cancelLabel.alpha = 1
}
// 添加重力动画效果
UIView.animate(withDuration: 1.1,
delay: 0.2,
usingSpringWithDamping: 0.5, // 弹性系数,越小弹性越大
initialSpringVelocity: 0.8, // 初始速度
options: .curveEaseIn,
animations: {
// 设置最终位置
self.dropImage.frame = CGRect(x: (ScreenW - dropW)/2.0,
y: kSafeAreaInsets.top + 129.RH(), // 根据原来的约束位置计算
width: dropW,
height: dropH)
}, completion: nil)
// UIView.animate(withDuration: 1.1,
// delay: 0.2,
// usingSpringWithDamping: 0.5, // 弹性系数,越小弹性越大
// initialSpringVelocity: 0.8, // 初始速度
// options: .curveEaseIn,
// animations: {
// // 设置最终位置
// self.dropImage.frame = CGRect(x: (ScreenW - dropW)/2.0,
// y: kSafeAreaInsets.top + 129.RH(), // 根据原来的约束位置计算
// width: dropW,
// height: dropH)
//
// self.offerImage.frame = CGRect(x: (ScreenW - 111) / 2,
// y: kSafeAreaInsets.top + 70,
// width: 111,
// height: 37)
//
// self.distanceL.frame = CGRect(x: (ScreenW - 270) / 2,
// y: kSafeAreaInsets.top + CGFloat(129.RH()) + dropH + CGFloat(40.RH()),
// width: 270,
// height: 40)
//
// self.annual.frame = CGRect(x: (ScreenW - 150) / 2,
// y: self.distanceL.frame.maxY + CGFloat(115.RH()),
// width: 150,
// height: 22)
//
// self.yearDistacePrice.frame = CGRect(x: (ScreenW - 200) / 2,
// y: self.annual.frame.maxY + 8,
// width: 200,
// height: 22)
//
// self.cancelLabel.frame = CGRect(x: (ScreenW - 150) / 2,
// y: self.yearDistacePrice.frame.maxY,
// width: 150,
// height: 22)
// }, completion: nil)
// offerImage.frame = CGRect(x: (ScreenW - 111) / 2, y: -37, width: 111, height: 37)
// distanceL.frame = CGRect(x: (ScreenW - 270) / 2, y: -40, width: 270, height: 40)
// annual.frame = CGRect(x: (ScreenW - 150) / 2, y: -30, width: 150, height: 22)
// yearDistacePrice.frame = CGRect(x: (ScreenW - 200) / 2, y: -30, width: 200, height: 22)
// cancelLabel.frame = CGRect(x: (ScreenW - 150) / 2, y: -30, width: 150, height: 22)
//
// // 添加下落动画
// UIView.animate(withDuration: 0.3,
// delay: 0, // 稍微延迟一点,让动画错开
// options: .curveEaseOut) {
// // 设置最终位置
// self.offerImage.frame = CGRect(x: (ScreenW - 111) / 2,
// y: kSafeAreaInsets.top + 70,
// width: 111,
// height: 37)
//
// self.distanceL.frame = CGRect(x: (ScreenW - 270) / 2,
// y: kSafeAreaInsets.top + CGFloat(129.RH()) + dropH + CGFloat(40.RH()),
// width: 270,
// height: 40)
//
// self.annual.frame = CGRect(x: (ScreenW - 150) / 2,
// y: self.distanceL.frame.maxY + CGFloat(115.RH()),
// width: 150,
// height: 22)
//
// self.yearDistacePrice.frame = CGRect(x: (ScreenW - 200) / 2,
// y: self.annual.frame.maxY + 8,
// width: 200,
// height: 22)
//
// self.cancelLabel.frame = CGRect(x: (ScreenW - 150) / 2,
// y: self.yearDistacePrice.frame.maxY,
// width: 150,
// height: 22)
//
// }
// 添加呼吸动画
......
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