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(){
//
//
// }
}
//
// 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)
......
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