diff --git a/Example/Base.lproj/Main.storyboard b/Example/Base.lproj/Main.storyboard index 214f6c2e..6155237a 100644 --- a/Example/Base.lproj/Main.storyboard +++ b/Example/Base.lproj/Main.storyboard @@ -52,14 +52,28 @@ + + + diff --git a/Example/ViewController.swift b/Example/ViewController.swift index a36de3fb..dfc41967 100644 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -47,6 +47,39 @@ class ViewController: UIViewController { print(finish.timeIntervalSince(start)) }) } + + private var lastSelectedAlbum: String? + @IBAction func showImagePickerWithAlbums(_ sender: UIButton) { + let imagePicker = ImagePickerController() + imagePicker.settings.selection.max = 3 + imagePicker.settings.theme.selectionStyle = .checked + imagePicker.settings.fetch.assets.supportedMediaTypes = [.image, .video] + imagePicker.settings.selection.unselectOnReachingMax = false + + imagePicker.selectedAlbumIdentifier = lastSelectedAlbum + //Show the "Recent" album and all other ones available + let options = imagePicker.settings.fetch.album.options + imagePicker.settings.fetch.album.fetchResults = [ + PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: options), + PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumRegular, options: options), + ] + + let start = Date() + self.presentImagePicker(imagePicker, select: { (asset) in + print("Selected: \(asset)") + }, deselect: { (asset) in + print("Deselected: \(asset)") + }, cancel: { [weak self] (assets) in + self?.lastSelectedAlbum = imagePicker.selectedAlbumIdentifier + print("Canceled with selections: \(assets)") + }, finish: { [weak self] (assets) in + self?.lastSelectedAlbum = imagePicker.selectedAlbumIdentifier + print("Finished with selections: \(assets)") + }, completion: { + let finish = Date() + print(finish.timeIntervalSince(start)) + }) + } @IBAction func showCustomImagePicker(_ sender: UIButton) { let imagePicker = ImagePickerController() diff --git a/Sources/Controller/ImagePickerController.swift b/Sources/Controller/ImagePickerController.swift index b3a4af0f..b070743f 100644 --- a/Sources/Controller/ImagePickerController.swift +++ b/Sources/Controller/ImagePickerController.swift @@ -47,6 +47,7 @@ import Photos var onDeselection: ((_ asset: PHAsset) -> Void)? var onCancel: ((_ assets: [PHAsset]) -> Void)? var onFinish: ((_ assets: [PHAsset]) -> Void)? + public var selectedAlbumIdentifier: String? let assetsViewController: AssetsViewController let albumsViewController = AlbumsViewController() @@ -137,7 +138,10 @@ import Photos navigationBar.barTintColor = .systemBackgroundColor } - if let firstAlbum = albums.first { + if let selectedAlbumIdentifier = selectedAlbumIdentifier, let selectedAlbum = albums.first(where: { $0.localIdentifier == selectedAlbumIdentifier }) { + select(album: selectedAlbum) + } else if let firstAlbum = albums.first { + selectedAlbumIdentifier = firstAlbum.localIdentifier //so the check mark appears in the albums list select(album: firstAlbum) } } diff --git a/Sources/Scene/Albums/AlbumsViewController.swift b/Sources/Scene/Albums/AlbumsViewController.swift index 72bed40a..c41e9e0e 100755 --- a/Sources/Scene/Albums/AlbumsViewController.swift +++ b/Sources/Scene/Albums/AlbumsViewController.swift @@ -24,6 +24,7 @@ import UIKit import Photos protocol AlbumsViewControllerDelegate: class { + var selectedAlbumIdentifier: String? { get set } func albumsViewController(_ albumsViewController: AlbumsViewController, didSelectAlbum album: PHAssetCollection) func didDismissAlbumsViewController(_ albumsViewController: AlbumsViewController) } @@ -71,6 +72,33 @@ class AlbumsViewController: UIViewController { modalPresentationStyle = .popover preferredContentSize = CGSize(width: 320, height: 300) } + + private var firstScreenShow = true + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + if firstScreenShow { //on the first show the function does not affect the tableView content offset/scroll + DispatchQueue.main.async { [weak self] in + self?.selectAlbumCellAndScroll() + } + } else { + selectAlbumCellAndScroll() + } + firstScreenShow = false + } + + private func selectAlbumCellAndScroll() { + if let selectedAlbum = delegate?.selectedAlbumIdentifier, let albumIndex = albums.firstIndex(where: { $0.localIdentifier == selectedAlbum }), albumIndex != NSNotFound { + var indexPathsForReload = [IndexPath]() + if let indexPath = tableView.indexPathForSelectedRow, indexPath.row != albumIndex { + indexPathsForReload.append(indexPath) + } + let selectedIndexPath = IndexPath(row: albumIndex, section: 0) + indexPathsForReload.append(selectedIndexPath) + tableView.reloadRows(at: indexPathsForReload, with: .none) + tableView.scrollToRow(at: selectedIndexPath, at: .top, animated: false) //.middle works badly as only 2 elements fit the table + } + } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) @@ -86,8 +114,16 @@ class AlbumsViewController: UIViewController { } extension AlbumsViewController: UITableViewDelegate { + + func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + if let selectedAlbum = delegate?.selectedAlbumIdentifier, let albumIndex = albums.firstIndex(where: { $0.localIdentifier == selectedAlbum }) { + cell.isSelected = indexPath.row == albumIndex + } + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let album = albums[indexPath.row] + delegate?.selectedAlbumIdentifier = album.localIdentifier delegate?.albumsViewController(self, didSelectAlbum: album) }