diff --git a/ALCameraViewController/Utilities/ImageFetcher.swift b/ALCameraViewController/Utilities/ImageFetcher.swift index 09c4ea9f..a20fe0af 100644 --- a/ALCameraViewController/Utilities/ImageFetcher.swift +++ b/ALCameraViewController/Utilities/ImageFetcher.swift @@ -61,4 +61,20 @@ public class ImageFetcher { } } } + + public static func resolveAssets(_ assets: [PHAsset], size: CGSize = CGSize(width: 720, height: 1280)) -> [UIImage] { + let imageManager = PHImageManager.default() + let requestOptions = PHImageRequestOptions() + requestOptions.isSynchronous = true + + var images = [UIImage]() + for asset in assets { + imageManager.requestImage(for: asset, targetSize: size, contentMode: .aspectFill, options: requestOptions) { image, _ in + if let image = image { + images.append(image) + } + } + } + return images + } } diff --git a/ALCameraViewController/ViewController/CameraViewController.swift b/ALCameraViewController/ViewController/CameraViewController.swift index d9e07099..a03a7634 100644 --- a/ALCameraViewController/ViewController/CameraViewController.swift +++ b/ALCameraViewController/ViewController/CameraViewController.swift @@ -41,6 +41,20 @@ public extension CameraViewController { return navigationController } + + /// Provides an multiple image picker wrapped inside a UINavigationController instance + public class func imagePickerViewController(completion: @escaping PhotoLibraryViewMultipleSelectionComplete) -> UINavigationController { + let imagePicker = PhotoLibraryViewController() + imagePicker.allowsMultipleSelection = true + imagePicker.onMultipleSelectionComplete = completion + + let navigationController = UINavigationController(rootViewController: imagePicker) + navigationController.navigationBar.barTintColor = UIColor.black + navigationController.navigationBar.barStyle = UIBarStyle.black + navigationController.modalTransitionStyle = UIModalTransitionStyle.crossDissolve + + return navigationController + } } open class CameraViewController: UIViewController { diff --git a/ALCameraViewController/ViewController/PhotoLibraryViewController.swift b/ALCameraViewController/ViewController/PhotoLibraryViewController.swift index 8bdc9cd6..9d0b8a68 100644 --- a/ALCameraViewController/ViewController/PhotoLibraryViewController.swift +++ b/ALCameraViewController/ViewController/PhotoLibraryViewController.swift @@ -14,12 +14,16 @@ internal let ImageCellIdentifier = "ImageCell" internal let defaultItemSpacing: CGFloat = 1 public typealias PhotoLibraryViewSelectionComplete = (PHAsset?) -> Void +public typealias PhotoLibraryViewMultipleSelectionComplete = ([PHAsset]?) -> Void public class PhotoLibraryViewController: UIViewController { internal var assets: PHFetchResult? = nil + /// Controls whether multiple cells can be selected, default is `false`. + public var allowsMultipleSelection = false public var onSelectionComplete: PhotoLibraryViewSelectionComplete? + public var onMultipleSelectionComplete: PhotoLibraryViewMultipleSelectionComplete? private lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() @@ -32,6 +36,7 @@ public class PhotoLibraryViewController: UIViewController { let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout) collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.backgroundColor = UIColor.clear + collectionView.allowsMultipleSelection = self.allowsMultipleSelection return collectionView }() @@ -47,6 +52,12 @@ public class PhotoLibraryViewController: UIViewController { target: self, action: #selector(dismissLibrary)) + if allowsMultipleSelection { + navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, + target: self, + action: #selector(selectMultiple)) + } + view.backgroundColor = UIColor(white: 0.2, alpha: 1) view.addSubview(collectionView) @@ -73,7 +84,12 @@ public class PhotoLibraryViewController: UIViewController { } @objc public func dismissLibrary() { - onSelectionComplete?(nil) + allowsMultipleSelection ? onMultipleSelectionComplete?(nil) : onSelectionComplete?(nil) + } + + @objc public func selectMultiple() { + let assets: [PHAsset]? = collectionView.indexPathsForSelectedItems?.flatMap { self.itemAtIndexPath($0) } + onMultipleSelectionComplete?(assets) } private func onSuccess(_ photos: PHFetchResult) { @@ -122,6 +138,23 @@ extension PhotoLibraryViewController : UICollectionViewDataSource { // MARK: - UICollectionViewDelegate - extension PhotoLibraryViewController : UICollectionViewDelegateFlowLayout { public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard !allowsMultipleSelection else { + return + } onSelectionComplete?(itemAtIndexPath(indexPath)) } + + public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { + guard allowsMultipleSelection else { + return true + } + + if let selectedItems = collectionView.indexPathsForSelectedItems { + if selectedItems.contains(indexPath) { + collectionView.deselectItem(at: indexPath, animated: true) + return false + } + } + return true + } } diff --git a/ALCameraViewController/Views/ImageCell.swift b/ALCameraViewController/Views/ImageCell.swift index b05053c0..ff05045a 100644 --- a/ALCameraViewController/Views/ImageCell.swift +++ b/ALCameraViewController/Views/ImageCell.swift @@ -42,6 +42,13 @@ class ImageCell: UICollectionViewCell { compatibleWith: nil) } + override var isSelected: Bool { + didSet { + contentView.layer.borderWidth = 2.0 + contentView.layer.borderColor = isSelected ? UIColor.blue.cgColor : UIColor.clear.cgColor + } + } + func configureWithModel(_ model: PHAsset) { if tag != 0 { diff --git a/Example/ViewController.swift b/Example/ViewController.swift index e4c6aa1b..eb0ed6bb 100644 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -23,7 +23,8 @@ class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var croppingParametersView: UIView! @IBOutlet weak var minimumSizeLabel: UILabel! - + @IBOutlet weak var multipleSelectionSwitch: UISwitch! + override func viewDidLoad() { super.viewDidLoad() @@ -40,12 +41,23 @@ class ViewController: UIViewController { } @IBAction func openLibrary(_ sender: Any) { - let libraryViewController = CameraViewController.imagePickerViewController(croppingParameters: croppingParameters) { [weak self] image, asset in - self?.imageView.image = image - self?.dismiss(animated: true, completion: nil) + if multipleSelectionSwitch.isOn { + let libraryViewController = CameraViewController.imagePickerViewController(completion: { [weak self] assets in + if let assets = assets { + let images = ImageFetcher.resolveAssets(assets, size: largestPhotoSize()) + self?.imageView.image = images.last + } + self?.dismiss(animated: true, completion: nil) + }) + present(libraryViewController, animated: true, completion: nil) + } else { + let libraryViewController = CameraViewController.imagePickerViewController(croppingParameters: croppingParameters) { + [weak self] image, asset in + self?.imageView.image = image + self?.dismiss(animated: true, completion: nil) + } + present(libraryViewController, animated: true, completion: nil) } - - present(libraryViewController, animated: true, completion: nil) } @IBAction func libraryChanged(_ sender: Any) { diff --git a/Example/ViewController.xib b/Example/ViewController.xib index 969010cb..33add9a0 100644 --- a/Example/ViewController.xib +++ b/Example/ViewController.xib @@ -1,11 +1,11 @@ - + - + @@ -20,6 +20,7 @@ + @@ -28,11 +29,8 @@ - - - - + + + +