Этот исходный код представляет собой приложение для фотографий, подобное приложению для фотографий iPhone.Когда вы запускаете приложение, отображается каждый Asset
, то есть CollectionViewCell
.
Я хотел бы спросить, есть ли возможность выбрать и удалить актив изображения.Если вы посмотрите на приложение для фотографий iPhone, вы можете нажать кнопку выбора, чтобы выбрать фотографии, а также удалить и поделиться выбранными фотографиями.Вы можете выбрать столько фотографий, сколько хотите, а не только одну.Я реализовал @IBAction selectButtonPressed
.
class PhotoCollectionViewController: UICollectionViewController {
@IBOutlet weak var sortButton: UIBarButtonItem!
@IBOutlet weak var selectButton: UIBarButtonItem!
@IBOutlet weak var actionButton: UIBarButtonItem!
@IBOutlet weak var trashButton: UIBarButtonItem!
// MARK:- Properties
var fetchResult: PHFetchResult<PHAsset>? {
didSet {
OperationQueue.main.addOperation {
self.collectionView?.reloadSections(IndexSet(0...0))
}
}
}
var assetCollection: PHAssetCollection?
// MARK:- Privates
private let cellReuseIdentifier: String = "photoCell"
private lazy var cachingImageManager: PHCachingImageManager = {
return PHCachingImageManager()
}()
// MARK:- Life Cycle
deinit {
PHPhotoLibrary.shared().unregisterChangeObserver(self)
}
@IBAction func sortButtonPressed(_ sender: UIBarButtonItem) {
let fetchOptions: PHFetchOptions = PHFetchOptions()
if (self.sortButton.title == "In the past") {
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "modificationDate",
ascending: false)]
self.fetchResult = PHAsset.fetchAssets(in: assetCollection!, options: fetchOptions )
self.sortButton.title = "The latest"
} else if (self.sortButton.title == "The latest") {
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",
ascending: true)]
self.fetchResult = PHAsset.fetchAssets(in: assetCollection!, options: fetchOptions )
self.sortButton.title = "In the past"
}
}
@IBAction func seletButtonPressed(_ sender: Any) {
if (self.sortButton.isEnabled == true) {
self.sortButton.isEnabled = false
self.actionButton.isEnabled = true
self.trashButton.isEnabled = true
} else if (self.sortButton.isEnabled == false) {
self.sortButton.isEnabled = true
self.actionButton.isEnabled = false
self.trashButton.isEnabled = false
}
PHPhotoLibrary.shared().performChanges({
//Delete Photo
PHAssetChangeRequest.deleteAssets(self.fetchResult!)
},
completionHandler: {(success, error)in
NSLog("\nDeleted Image -> %@", (success ? "Success":"Error!"))
if(success){
}else{
print("Error: \(error)")
}
})
}
}
extension PhotoCollectionViewController {
private func configureCell(_ cell: PhotoCollectionViewCell,
collectionView: UICollectionView,
indexPath: IndexPath) {
guard let asset: PHAsset = self.fetchResult?.object(at: indexPath.item) else { return }
let manager: PHCachingImageManager = self.cachingImageManager
let handler: (UIImage?, [AnyHashable:Any]?) -> Void = { image, _ in
let cellAtIndex: UICollectionViewCell? = collectionView.cellForItem(at: indexPath)
guard let cell: PhotoCollectionViewCell = cellAtIndex as? PhotoCollectionViewCell
else { return }
cell.imageView.image = image
}
manager.requestImage(for: asset,
targetSize: CGSize(width: 100, height: 100),
contentMode: PHImageContentMode.aspectFill,
options: nil,
resultHandler: handler)
}
}
// MARK:- UICollectionViewDataSource
extension PhotoCollectionViewController {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return self.fetchResult?.count ?? 0
}
}
extension PhotoCollectionViewController {
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: PhotoCollectionViewCell
cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellReuseIdentifier,
for: indexPath) as! PhotoCollectionViewCell
return cell
}
override func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
guard let cell: PhotoCollectionViewCell = cell as? PhotoCollectionViewCell else {
return
}
self.configureCell(cell, collectionView: collectionView, indexPath: indexPath)
}
}
// MARK:- UICollectionViewDelegateFlowLayout
extension PhotoCollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
guard let flowLayout: UICollectionViewFlowLayout =
self.collectionViewLayout as? UICollectionViewFlowLayout else { return CGSize.zero}
let numberOfCellsInRow: CGFloat = 4
let viewSize: CGSize = self.view.frame.size
let sectionInset: UIEdgeInsets = flowLayout.sectionInset
let interitemSpace: CGFloat = flowLayout.minimumInteritemSpacing * (numberOfCellsInRow - 1)
var itemWidth: CGFloat
itemWidth = viewSize.width - sectionInset.left - sectionInset.right - interitemSpace
itemWidth /= numberOfCellsInRow
let itemSize = CGSize(width: itemWidth, height: itemWidth)
return itemSize
}
}
extension PhotoCollectionViewController {
private func updateCollectionView(with changes: PHFetchResultChangeDetails<PHAsset>) {
guard let collectionView = self.collectionView else { return }
// 업데이트는 삭제, 삽입, 다시 불러오기, 이동 순으로 진행합니다
if let removed: IndexSet = changes.removedIndexes, removed.count > 0 {
collectionView.deleteItems(at: removed.map({
IndexPath(item: $0, section: 0)
}))
}
if let inserted: IndexSet = changes.insertedIndexes, inserted.count > 0 {
collectionView.insertItems(at: inserted.map({
IndexPath(item: $0, section: 0)
}))
}
if let changed: IndexSet = changes.changedIndexes, changed.count > 0 {
collectionView.reloadItems(at: changed.map({
IndexPath(item: $0, section: 0)
}))
}
changes.enumerateMoves { fromIndex, toIndex in
collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0),
to: IndexPath(item: toIndex, section: 0))
}
}
}
// MARK:- PHPhotoLibraryChangeObserver
extension PhotoCollectionViewController: PHPhotoLibraryChangeObserver {
private func resetCachedAssets() {
self.cachingImageManager.stopCachingImagesForAllAssets()
}
func photoLibraryDidChange(_ changeInstance: PHChange) {
guard let fetchResult: PHFetchResult<PHAsset> = self.fetchResult
else { return }
guard let changes: PHFetchResultChangeDetails<PHAsset> =
changeInstance.changeDetails(for: fetchResult)
else { return }
DispatchQueue.main.sync {
self.resetCachedAssets()
self.fetchResult = changes.fetchResultAfterChanges
if changes.hasIncrementalChanges {
self.updateCollectionView(with: changes)
} else {
self.collectionView?.reloadSections(IndexSet(0...0))
}
}
}
}
extension PhotoCollectionViewController {
// MARK:- Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
PHPhotoLibrary.shared().register(self)
self.sortButton.title = "In the past"
self.actionButton.isEnabled = false
self.trashButton.isEnabled = false
}
}
AssetCollection
, можно выбрать, нажав select
barButtonItem
в правом верхнем углу экрана, и я хочу удалить или поделиться выбранными снимками.