|
@@ -7,14 +7,51 @@
|
|
|
|
|
|
import UIKit
|
|
|
import PhotosUI
|
|
|
-
|
|
|
+import HXPhotoPicker
|
|
|
class TSPhotoPickerManager: NSObject {
|
|
|
+ lazy var config: PickerConfiguration = {
|
|
|
+ var config = PickerConfiguration()
|
|
|
+ config.modalPresentationStyle = .automatic
|
|
|
+ config.selectOptions = .photo
|
|
|
+ config.selectMode = .single
|
|
|
+ config.isSelectedOriginal = true
|
|
|
+ config.photoList.sort = .desc
|
|
|
+ config.photoSelectionTapAction = .quickSelect
|
|
|
+ config.photoList.finishSelectionAfterTakingPhoto = true
|
|
|
+ config.photoList.isSaveSystemAlbum = false
|
|
|
+ config.photoList.takePictureCompletionToSelected = true
|
|
|
+
|
|
|
+ var cameraConfig = SystemCameraConfiguration()
|
|
|
+ cameraConfig.allowsEditing = false
|
|
|
+ config.photoList.cameraType = .system(cameraConfig)
|
|
|
+ return config
|
|
|
+ }()
|
|
|
+
|
|
|
+ var picker: PhotoPickerController?
|
|
|
+ lazy var multipleConfig: PickerConfiguration = {
|
|
|
+ var config = PickerConfiguration()
|
|
|
+ config.modalPresentationStyle = .automatic
|
|
|
+ config.selectOptions = .photo
|
|
|
+ config.selectMode = .multiple
|
|
|
+ config.maximumSelectedCount = 2
|
|
|
+ config.isSelectedOriginal = true
|
|
|
+ config.photoList.sort = .desc
|
|
|
+ config.photoSelectionTapAction = .preview
|
|
|
+ config.photoList.finishSelectionAfterTakingPhoto = false
|
|
|
+ config.photoList.isSaveSystemAlbum = false
|
|
|
+ config.photoList.takePictureCompletionToSelected = true
|
|
|
+ var cameraConfig = SystemCameraConfiguration()
|
|
|
+ cameraConfig.allowsEditing = false
|
|
|
+ config.photoList.cameraType = .system(cameraConfig)
|
|
|
+ return config
|
|
|
+ }()
|
|
|
+
|
|
|
+
|
|
|
|
|
|
// MARK: - Properties
|
|
|
private weak var viewController: UIViewController?
|
|
|
- private var completionHandler: ((UIImage?,PHAsset?) -> Void)?
|
|
|
- private var completionSizeHandler: ((UIImage?,String?) -> Void)?
|
|
|
- private var imagePicker = UIImagePickerController()
|
|
|
+ private var completionHandler: (([UIImage]) -> Void)?
|
|
|
+ private var maxSelected:Int = 1
|
|
|
// MARK: - Initializers
|
|
|
init(viewController: UIViewController) {
|
|
|
self.viewController = viewController
|
|
@@ -22,8 +59,9 @@ class TSPhotoPickerManager: NSObject {
|
|
|
|
|
|
// MARK: - Public Methods
|
|
|
/// 打开照片选择器,单选一张照片
|
|
|
- func pickSinglePhoto(completion: @escaping (UIImage?,PHAsset?) -> Void) {
|
|
|
+ func pickPhoto(maxSelected:Int = 1,completion: @escaping ([UIImage]) -> Void) {
|
|
|
self.completionHandler = completion
|
|
|
+ self.maxSelected = maxSelected
|
|
|
// 检查相册权限
|
|
|
checkPhotoLibraryPermission { [weak self] authorized in
|
|
|
guard let self = self else { return }
|
|
@@ -55,23 +93,18 @@ class TSPhotoPickerManager: NSObject {
|
|
|
|
|
|
/// 打开照片选择器
|
|
|
private func openPhotoPicker() {
|
|
|
- TSToastShared.showLoading(containerView: viewController?.view)
|
|
|
- imagePicker = UIImagePickerController()
|
|
|
- imagePicker.sourceType = .photoLibrary
|
|
|
- imagePicker.delegate = self
|
|
|
- imagePicker.mediaTypes = ["public.image"] // 只选择照片
|
|
|
-// imagePicker.modalPresentationStyle = .custom
|
|
|
-// imagePicker.modalTransitionStyle = .crossDissolve
|
|
|
- if #available(iOS 13.0, *) {
|
|
|
- imagePicker.overrideUserInterfaceStyle = .dark
|
|
|
- }
|
|
|
- viewController?.present(imagePicker, animated: true){
|
|
|
- TSToastShared.hideLoading()
|
|
|
- }
|
|
|
|
|
|
- kMainAfter(3.0) {
|
|
|
- TSToastShared.hideLoading()
|
|
|
+ var config = config
|
|
|
+ if maxSelected > 1 {
|
|
|
+ config = multipleConfig
|
|
|
+ config.maximumSelectedCount = maxSelected
|
|
|
}
|
|
|
+
|
|
|
+ let picker = PhotoPickerController(splitPicker: config)
|
|
|
+ picker.pickerDelegate = self
|
|
|
+ picker.autoDismiss = false
|
|
|
+ viewController?.present(picker, animated: true, completion: nil)
|
|
|
+ self.picker = picker
|
|
|
}
|
|
|
|
|
|
/// 显示权限提示
|
|
@@ -93,88 +126,195 @@ class TSPhotoPickerManager: NSObject {
|
|
|
deinit {
|
|
|
debugPrint("♻️♻️♻️ TSPhotoPickerManager -> TSPhotoPickerManager deinit ♻️♻️♻️")
|
|
|
}
|
|
|
+
|
|
|
+ func dismissPageVC(){
|
|
|
+ self.picker?.view.isHidden = true
|
|
|
+ self.picker?.dismiss(animated: false)
|
|
|
+ self.picker = nil
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-// MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate (iOS 14 以下)
|
|
|
-extension TSPhotoPickerManager: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
|
|
- func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
|
|
|
-// picker.dismiss(animated: true) {
|
|
|
- if let image = info[.originalImage] as? UIImage {
|
|
|
- self.completionHandler?(image,info[.phAsset] as? PHAsset )
|
|
|
- } else {
|
|
|
- self.completionHandler?(nil,nil)
|
|
|
- }
|
|
|
-// }
|
|
|
-
|
|
|
- if completionSizeHandler == nil {
|
|
|
- picker.dismiss(animated: true, completion: nil)
|
|
|
+extension TSPhotoPickerManager: PhotoPickerControllerDelegate {
|
|
|
+ func pickerController(_ pickerController: PhotoPickerController, didFinishSelection result: PickerResult) {
|
|
|
+ result.getImage(compressionScale: 1.0) { images in
|
|
|
+ self.completionHandler?(images)
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
|
|
-// self.completionHandler?(nil,nil)
|
|
|
-// if completionSizeHandler == nil {
|
|
|
- picker.dismiss(animated: true, completion: nil)
|
|
|
-// }
|
|
|
+ func pickerController(didCancel pickerController: PhotoPickerController) {
|
|
|
+ pickerController.dismiss(animated: true, completion: nil)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
-extension TSPhotoPickerManager{
|
|
|
-
|
|
|
- func pickCustomSinglePhoto(completion: @escaping (UIImage?,String?) -> Void) {
|
|
|
- self.completionSizeHandler = completion
|
|
|
- pickSinglePhoto { [weak self] image,phAsset in
|
|
|
- guard let self = self else { return }
|
|
|
- self.completionSizeHandler?(image,nil)
|
|
|
- self.completionSizeHandler = nil
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // MARK: - Public Methods
|
|
|
- /// 打开照片选择器,单选一张照片
|
|
|
- func pickSinglePhoto(maxBitSize:Int, completion: @escaping (UIImage?,String?) -> Void) {
|
|
|
- self.completionSizeHandler = completion
|
|
|
-
|
|
|
- let maxmbSize = Int(Double(maxBitSize) / (1024 * 1024))
|
|
|
- pickSinglePhoto { [weak self] image,phAsset in
|
|
|
- guard let self = self else { return }
|
|
|
- if let image = image,let phAsset = phAsset {
|
|
|
- // 方法2:异步获取详细大小(不阻塞主线程)
|
|
|
- TSPhotoSizeHelper.getImageFileSizeAsync(asset: phAsset) {[weak self] size in
|
|
|
- guard let self = self else { return }
|
|
|
-
|
|
|
- let mbSize = Double(size) / (1024 * 1024)
|
|
|
- print("精确大小: \(mbSize) MB,size = \(size)")
|
|
|
- if size > maxBitSize {
|
|
|
- self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
|
|
|
- }else{
|
|
|
- self.completionSizeHandler?(image,nil)
|
|
|
- self.completionSizeHandler = nil
|
|
|
-// imagePicker.dismiss(animated: true)
|
|
|
- }
|
|
|
- }
|
|
|
- }else{
|
|
|
- if let image = image {
|
|
|
- if image.isLargerThan(byteSize: maxBitSize) {
|
|
|
- self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
|
|
|
- }else{
|
|
|
- self.completionSizeHandler?(image,nil)
|
|
|
- self.completionSizeHandler = nil
|
|
|
-// imagePicker.dismiss(animated: true)
|
|
|
- }
|
|
|
- }else{
|
|
|
- self.completionSizeHandler?(nil,nil)
|
|
|
-// imagePicker.dismiss(animated: true)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- func dismissPageVC(){
|
|
|
- self.imagePicker.view.isHidden = true
|
|
|
- self.imagePicker.dismiss(animated: true)
|
|
|
- }
|
|
|
-}
|
|
|
+//class TSPhotoPickerManager: NSObject {
|
|
|
+//
|
|
|
+// // MARK: - Properties
|
|
|
+// private weak var viewController: UIViewController?
|
|
|
+// private var completionHandler: ((UIImage?,PHAsset?) -> Void)?
|
|
|
+// private var completionSizeHandler: ((UIImage?,String?) -> Void)?
|
|
|
+// private var imagePicker = UIImagePickerController()
|
|
|
+// // MARK: - Initializers
|
|
|
+// init(viewController: UIViewController) {
|
|
|
+// self.viewController = viewController
|
|
|
+// }
|
|
|
+//
|
|
|
+// // MARK: - Public Methods
|
|
|
+// /// 打开照片选择器,单选一张照片
|
|
|
+// func pickSinglePhoto(completion: @escaping (UIImage?,PHAsset?) -> Void) {
|
|
|
+// self.completionHandler = completion
|
|
|
+// // 检查相册权限
|
|
|
+// checkPhotoLibraryPermission { [weak self] authorized in
|
|
|
+// guard let self = self else { return }
|
|
|
+// if authorized {
|
|
|
+// self.openPhotoPicker()
|
|
|
+// } else {
|
|
|
+// self.showPermissionAlert()
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// // MARK: - Private Methods
|
|
|
+// /// 检查相册权限
|
|
|
+// private func checkPhotoLibraryPermission(completion: @escaping (Bool) -> Void) {
|
|
|
+// let status = PHPhotoLibrary.authorizationStatus()
|
|
|
+// switch status {
|
|
|
+// case .authorized:
|
|
|
+// completion(true)
|
|
|
+// case .notDetermined:
|
|
|
+// PHPhotoLibrary.requestAuthorization { newStatus in
|
|
|
+// DispatchQueue.main.async {
|
|
|
+// completion(newStatus == .authorized)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// default:
|
|
|
+// completion(false)
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// /// 打开照片选择器
|
|
|
+// private func openPhotoPicker() {
|
|
|
+// TSToastShared.showLoading(containerView: viewController?.view)
|
|
|
+// imagePicker = UIImagePickerController()
|
|
|
+// imagePicker.sourceType = .photoLibrary
|
|
|
+// imagePicker.delegate = self
|
|
|
+// imagePicker.mediaTypes = ["public.image"] // 只选择照片
|
|
|
+//// imagePicker.modalPresentationStyle = .custom
|
|
|
+//// imagePicker.modalTransitionStyle = .crossDissolve
|
|
|
+// if #available(iOS 13.0, *) {
|
|
|
+// imagePicker.overrideUserInterfaceStyle = .dark
|
|
|
+// }
|
|
|
+// viewController?.present(imagePicker, animated: true){
|
|
|
+// TSToastShared.hideLoading()
|
|
|
+// }
|
|
|
+//
|
|
|
+// kMainAfter(3.0) {
|
|
|
+// TSToastShared.hideLoading()
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// /// 显示权限提示
|
|
|
+// private func showPermissionAlert() {
|
|
|
+// let alert = UIAlertController(
|
|
|
+// title: "No photos permission".localized,
|
|
|
+// message: "Please enable photo permission in settings to select photos".localized,
|
|
|
+// preferredStyle: .alert
|
|
|
+// )
|
|
|
+// alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel, handler: nil))
|
|
|
+// alert.addAction(UIAlertAction(title: "Go to Settings".localized, style: .default) { _ in
|
|
|
+// if let url = URL(string: UIApplication.openSettingsURLString) {
|
|
|
+// UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
|
|
+// }
|
|
|
+// })
|
|
|
+// viewController?.present(alert, animated: true, completion: nil)
|
|
|
+// }
|
|
|
+//
|
|
|
+// deinit {
|
|
|
+// debugPrint("♻️♻️♻️ TSPhotoPickerManager -> TSPhotoPickerManager deinit ♻️♻️♻️")
|
|
|
+// }
|
|
|
+//}
|
|
|
+//
|
|
|
+//// MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate (iOS 14 以下)
|
|
|
+//extension TSPhotoPickerManager: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
|
|
+// func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
|
|
|
+//// picker.dismiss(animated: true) {
|
|
|
+// if let image = info[.originalImage] as? UIImage {
|
|
|
+// self.completionHandler?(image,info[.phAsset] as? PHAsset )
|
|
|
+// } else {
|
|
|
+// self.completionHandler?(nil,nil)
|
|
|
+// }
|
|
|
+//// }
|
|
|
+//
|
|
|
+// if completionSizeHandler == nil {
|
|
|
+// picker.dismiss(animated: true, completion: nil)
|
|
|
+// }
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+// func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
|
|
|
+//// self.completionHandler?(nil,nil)
|
|
|
+//// if completionSizeHandler == nil {
|
|
|
+// picker.dismiss(animated: true, completion: nil)
|
|
|
+//// }
|
|
|
+// }
|
|
|
+//}
|
|
|
+//
|
|
|
+//
|
|
|
+//
|
|
|
+//extension TSPhotoPickerManager{
|
|
|
+//
|
|
|
+// func pickCustomSinglePhoto(completion: @escaping (UIImage?,String?) -> Void) {
|
|
|
+// self.completionSizeHandler = completion
|
|
|
+// pickSinglePhoto { [weak self] image,phAsset in
|
|
|
+// guard let self = self else { return }
|
|
|
+// self.completionSizeHandler?(image,nil)
|
|
|
+// self.completionSizeHandler = nil
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// // MARK: - Public Methods
|
|
|
+// /// 打开照片选择器,单选一张照片
|
|
|
+// func pickSinglePhoto(maxBitSize:Int, completion: @escaping (UIImage?,String?) -> Void) {
|
|
|
+// self.completionSizeHandler = completion
|
|
|
+//
|
|
|
+// let maxmbSize = Int(Double(maxBitSize) / (1024 * 1024))
|
|
|
+// pickSinglePhoto { [weak self] image,phAsset in
|
|
|
+// guard let self = self else { return }
|
|
|
+// if let image = image,let phAsset = phAsset {
|
|
|
+// // 方法2:异步获取详细大小(不阻塞主线程)
|
|
|
+// TSPhotoSizeHelper.getImageFileSizeAsync(asset: phAsset) {[weak self] size in
|
|
|
+// guard let self = self else { return }
|
|
|
+//
|
|
|
+// let mbSize = Double(size) / (1024 * 1024)
|
|
|
+// print("精确大小: \(mbSize) MB,size = \(size)")
|
|
|
+// if size > maxBitSize {
|
|
|
+// self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
|
|
|
+// }else{
|
|
|
+// self.completionSizeHandler?(image,nil)
|
|
|
+// self.completionSizeHandler = nil
|
|
|
+//// imagePicker.dismiss(animated: true)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }else{
|
|
|
+// if let image = image {
|
|
|
+// if image.isLargerThan(byteSize: maxBitSize) {
|
|
|
+// self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
|
|
|
+// }else{
|
|
|
+// self.completionSizeHandler?(image,nil)
|
|
|
+// self.completionSizeHandler = nil
|
|
|
+//// imagePicker.dismiss(animated: true)
|
|
|
+// }
|
|
|
+// }else{
|
|
|
+// self.completionSizeHandler?(nil,nil)
|
|
|
+//// imagePicker.dismiss(animated: true)
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// func dismissPageVC(){
|
|
|
+// self.imagePicker.view.isHidden = true
|
|
|
+// self.imagePicker.dismiss(animated: true)
|
|
|
+// }
|
|
|
+//}
|