122 lines
3.7 KiB
Swift
122 lines
3.7 KiB
Swift
//
|
|
// PhotoPickerVC.swift
|
|
// QuickLocation
|
|
//
|
|
|
|
import UIKit
|
|
import Photos
|
|
|
|
final class PhotoPickerVC: BaseViewController {
|
|
|
|
override var isNavigationBarHidden: Bool { true }
|
|
override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent }
|
|
|
|
var onConfirm: (([UIImage]) -> Void)?
|
|
|
|
private let maxCount: Int
|
|
private let store = PhotoPickerStore()
|
|
private var rootView: PhotoPickerView!
|
|
private var selected: [PHAsset] = []
|
|
private var currentAlbumIndex = 0
|
|
private var isExporting = false
|
|
|
|
init(maxCount: Int = 9) {
|
|
self.maxCount = max(1, maxCount)
|
|
super.init(nibName: nil, bundle: nil)
|
|
modalPresentationStyle = .fullScreen
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func loadView() {
|
|
rootView = PhotoPickerView(store: store, maxCount: maxCount)
|
|
view = rootView
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
rootView.bindAlbumStore(store)
|
|
bind()
|
|
store.requestAccess { [weak self] granted in
|
|
guard let self else { return }
|
|
guard granted else {
|
|
DLToast.show(text: "请在设置中开启相册权限")
|
|
self.dismiss(animated: true)
|
|
return
|
|
}
|
|
self.store.reloadAlbums()
|
|
self.currentAlbumIndex = 0
|
|
self.rootView.reloadAlbums(currentIndex: 0)
|
|
self.rootView.reloadGrid()
|
|
}
|
|
}
|
|
|
|
private func bind() {
|
|
rootView.onClose = { [weak self] in
|
|
self?.dismiss(animated: true)
|
|
}
|
|
rootView.onToggleAlbum = { [weak self] in
|
|
guard let self else { return }
|
|
self.rootView.isAlbumOpen.toggle()
|
|
}
|
|
rootView.onPickAlbum = { [weak self] index in
|
|
guard let self, self.store.albums.indices.contains(index) else { return }
|
|
self.currentAlbumIndex = index
|
|
self.store.loadAssets(in: self.store.albums[index])
|
|
self.rootView.reloadAlbums(currentIndex: index)
|
|
self.rootView.reloadGrid()
|
|
self.rootView.isAlbumOpen = false
|
|
}
|
|
rootView.onSelectAsset = { [weak self] index in
|
|
self?.toggleAsset(at: index)
|
|
}
|
|
rootView.onPreview = { [weak self] in
|
|
self?.showPreview()
|
|
}
|
|
rootView.onConfirm = { [weak self] in
|
|
self?.confirmSelection()
|
|
}
|
|
}
|
|
|
|
private func toggleAsset(at index: Int) {
|
|
guard store.assets.indices.contains(index) else { return }
|
|
let asset = store.assets[index]
|
|
if let idx = selected.firstIndex(where: { $0.localIdentifier == asset.localIdentifier }) {
|
|
selected.remove(at: idx)
|
|
} else {
|
|
if selected.count >= maxCount {
|
|
rootView.showLimitToast()
|
|
return
|
|
}
|
|
selected.append(asset)
|
|
}
|
|
rootView.applySelection(selected.map(\.localIdentifier))
|
|
}
|
|
|
|
private func showPreview() {
|
|
guard !selected.isEmpty else { return }
|
|
let vc = PhotoPickerPreviewVC(assets: selected, startIndex: 0, store: store)
|
|
present(vc, animated: true)
|
|
}
|
|
|
|
private func confirmSelection() {
|
|
guard !isExporting else { return }
|
|
guard !selected.isEmpty else {
|
|
dismiss(animated: true)
|
|
return
|
|
}
|
|
isExporting = true
|
|
DLToast.showLoading()
|
|
store.requestFullImages(for: selected) { [weak self] images in
|
|
DLToast.dismiss()
|
|
guard let self else { return }
|
|
self.isExporting = false
|
|
self.dismiss(animated: true) {
|
|
self.onConfirm?(images)
|
|
}
|
|
}
|
|
}
|
|
}
|