From 48b51342b9ee8c4f1ba1b9b97a56558a81aa36a1 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Thu, 12 Oct 2017 17:28:52 +0200 Subject: [PATCH 1/8] dealing with issue https://github.com/inloop/image-picker/issues/3, it's a programmer's error when setting a reuse identifier to a custom nib of camera item. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f0a50fb..3a3568f 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,9 @@ func imagePicker(controller: ImagePickerController, didSelectActionItemAt index: Image picker provides a default camera cell that just shows a camera output and captures a photo when user taps it. -If you wish to implement fancier features you must provide your own subclass of `CameraCollectionViewCell` and implement dedicated methods. +If you wish to implement fancier features you must provide your own subclass of `CameraCollectionViewCell` or nib file with custom cell class subclassing it and implement dedicated methods. + +> Note: Please note, that custom nib's cell class must inherit from `CameraCollectionViewCell` and must not specify any reuse identifer. Image Picker is handling reuse identifiers internally. Supported features of whoose UI can be fully customized: - [x] taking photos, live photos, recording videos, flipping camera From 2a4d7deb474a1e8796dc01cd29e35f2a674dc932 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Fri, 13 Oct 2017 09:21:17 +0200 Subject: [PATCH 2/8] added API to programatically select/deselect asset items --- ExampleApp/ViewController.swift | 2 +- ImagePicker/ImagePickerController.swift | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ExampleApp/ViewController.swift b/ExampleApp/ViewController.swift index e9b9d5a..c9ecc03 100644 --- a/ExampleApp/ViewController.swift +++ b/ExampleApp/ViewController.swift @@ -269,7 +269,7 @@ class ViewController: UITableViewController { navigationController?.visibleViewController?.navigationItem.setRightBarButton(UIBarButtonItem(title: title, style: .plain, target: nil, action: nil), animated: true) } } - + } extension ViewController : ImagePickerControllerDelegate { diff --git a/ImagePicker/ImagePickerController.swift b/ImagePicker/ImagePickerController.swift index caf7a88..d485a3b 100644 --- a/ImagePicker/ImagePickerController.swift +++ b/ImagePicker/ImagePickerController.swift @@ -106,6 +106,31 @@ open class ImagePickerController : UIViewController { /// public weak var dataSource: ImagePickerControllerDataSource? + /// + /// Programatically select asset. + /// + public func selectAsset(at index: Int, animated: Bool, scrollPosition: UICollectionViewScrollPosition) { + let path = IndexPath(item: index, section: layoutConfiguration.sectionIndexForAssets) + collectionView.selectItem(at: path, animated: animated, scrollPosition: scrollPosition) + } + + /// + /// Programatically deselect asset. + /// + public func deselectAsset(at index: Int, animated: Bool) { + let path = IndexPath(item: index, section: layoutConfiguration.sectionIndexForAssets) + collectionView.deselectItem(at: path, animated: animated) + } + + /// + /// Programatically deselect all selected assets. + /// + public func deselectAllAssets(animated: Bool) { + for selectedPath in collectionView.indexPathsForSelectedItems ?? [] { + collectionView.deselectItem(at: selectedPath, animated: animated) + } + } + /// /// Access all currently selected images /// From c39a807af7ef4eeb2f084e2f7643279d00580e05 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Fri, 13 Oct 2017 09:29:50 +0200 Subject: [PATCH 3/8] updated docs --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a3568f..e5562d3 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,6 @@ Various kind of configuration is supported. All configuration should be done **b - to use your custom views for action, camera and asset items use `CellRegistrator` class - don't forget to set your `delegate` and `dataSource` if needed - to define a source of photos that should be available to pick up use view controller's `assetsFetchResultBlock` block -- to access selected assets use `selectedAssets` array ### Capture settings @@ -306,6 +305,16 @@ To see an example how to set up Image Picker as an input view of a view controll Optionaly, before presenting image picker, you can check if user has granted access permissions to Photos Library using `PHPhotoLibrary` API and ask for permissions. If you don't do it, image picker will take care of this automatically for you *after* it's presented. +## Accessing, selecting and deselecting asset items + +Image Picker has several convinience methods to work with asset items. + +- `selectedAssets` property returns an array of currently selected `PHAsset` items +- to access asset items at certain indexes, use `assets(at:)` and `asset(at:)` +- to programatically select an asset item use `selectAsset(at:animated:scrollPosition:)` +- to programatically deselect an asset item use `deselectAsset(at:animated:)` +- to programatically deselect all selected items use `deselectAllAssets(_:)` + ## Features to add 1. landscape layout for camera cell - video is already in landscape but cell must be wider to properly display it From 817adfe6128fb58e5ab9129d058371a69044c251 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Fri, 13 Oct 2017 09:38:48 +0200 Subject: [PATCH 4/8] fix #2 - added default value as nil to completion block --- ExampleApp/Custom Views/CameraCell.swift | 2 +- ExampleApp/Custom Views/LivePhotoCameraCell.swift | 2 +- ExampleApp/Custom Views/VideoCameraCell.swift | 2 +- ImagePicker/CameraCollectionViewCell.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ExampleApp/Custom Views/CameraCell.swift b/ExampleApp/Custom Views/CameraCell.swift index 9054c9b..ba6eb04 100644 --- a/ExampleApp/Custom Views/CameraCell.swift +++ b/ExampleApp/Custom Views/CameraCell.swift @@ -20,7 +20,7 @@ class CameraCell : CameraCollectionViewCell { } @IBAction func flipButtonTapped(_ sender: UIButton) { - flipCamera(nil) + flipCamera() } } diff --git a/ExampleApp/Custom Views/LivePhotoCameraCell.swift b/ExampleApp/Custom Views/LivePhotoCameraCell.swift index 1933c79..9647777 100644 --- a/ExampleApp/Custom Views/LivePhotoCameraCell.swift +++ b/ExampleApp/Custom Views/LivePhotoCameraCell.swift @@ -39,7 +39,7 @@ class LivePhotoCameraCell : CameraCollectionViewCell { } @IBAction func flipButtonTapped(_ sender: UIButton) { - flipCamera(nil) + flipCamera() } // MARK: Override Methods diff --git a/ExampleApp/Custom Views/VideoCameraCell.swift b/ExampleApp/Custom Views/VideoCameraCell.swift index a03ca58..eae3660 100644 --- a/ExampleApp/Custom Views/VideoCameraCell.swift +++ b/ExampleApp/Custom Views/VideoCameraCell.swift @@ -38,7 +38,7 @@ class VideoCameraCell : CameraCollectionViewCell { } @IBAction func flipButtonTapped(_ sender: UIButton) { - flipCamera(nil) + flipCamera() } // MARK: Override Methods diff --git a/ImagePicker/CameraCollectionViewCell.swift b/ImagePicker/CameraCollectionViewCell.swift index 810235d..52678d1 100644 --- a/ImagePicker/CameraCollectionViewCell.swift +++ b/ImagePicker/CameraCollectionViewCell.swift @@ -117,7 +117,7 @@ open class CameraCollectionViewCell : UICollectionViewCell { /// /// - parameter completion: A block is called as soon as camera is changed. /// - public func flipCamera(_ completion: (() -> Void)?) { + public func flipCamera(_ completion: (() -> Void)? = nil) { delegate?.flipCamera(completion) } From f9f031deb40a367b26b2a626817da06a787f07e6 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Fri, 13 Oct 2017 10:22:47 +0200 Subject: [PATCH 5/8] #1 methods marked with @objc so they can be used with target-action pattern --- ImagePicker/CameraCollectionViewCell.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ImagePicker/CameraCollectionViewCell.swift b/ImagePicker/CameraCollectionViewCell.swift index 52678d1..9d3e18e 100644 --- a/ImagePicker/CameraCollectionViewCell.swift +++ b/ImagePicker/CameraCollectionViewCell.swift @@ -117,29 +117,29 @@ open class CameraCollectionViewCell : UICollectionViewCell { /// /// - parameter completion: A block is called as soon as camera is changed. /// - public func flipCamera(_ completion: (() -> Void)? = nil) { + @objc public func flipCamera(_ completion: (() -> Void)? = nil) { delegate?.flipCamera(completion) } /// /// Takes a picture /// - public func takePicture() { + @objc public func takePicture() { delegate?.takePicture() } /// /// Takes a live photo. Please note that live photos must be enabled when configuring Image Picker. /// - public func takeLivePhoto() { + @objc public func takeLivePhoto() { delegate?.takeLivePhoto() } - public func startVideoRecording() { + @objc public func startVideoRecording() { delegate?.startVideoRecording() } - public func stopVideoRecording() { + @objc public func stopVideoRecording() { delegate?.stopVideoRecording() } From 1234e614c16d812eb9cb41573746e402e73e0ae7 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Fri, 13 Oct 2017 11:02:38 +0200 Subject: [PATCH 6/8] #4 setting camera roll rather than recently added as default fetch result --- ImagePicker/ImagePickerAssetModel.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ImagePicker/ImagePickerAssetModel.swift b/ImagePicker/ImagePickerAssetModel.swift index b03ec9c..9806cf6 100644 --- a/ImagePicker/ImagePickerAssetModel.swift +++ b/ImagePicker/ImagePickerAssetModel.swift @@ -26,16 +26,16 @@ final class ImagePickerAssetModel { lazy var imageManager = PHCachingImageManager() var thumbnailSize: CGSize? - /// Tryies to access smart album recently added and uses just fetchAssets as fallback + /// Tryies to access smart album .smartAlbumUserLibrary that should be `Camera Roll` and uses just fetchAssets as fallback private lazy var defaultFetchResult: PHFetchResult = { let assetsOptions = PHFetchOptions() assetsOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] assetsOptions.fetchLimit = 1000 - let collections = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumRecentlyAdded, options: nil) - if let recentlyAdded = collections.firstObject { - return PHAsset.fetchAssets(in: recentlyAdded, options: assetsOptions) + let collections = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil) + if let cameraRoll = collections.firstObject { + return PHAsset.fetchAssets(in: cameraRoll, options: assetsOptions) } else { return PHAsset.fetchAssets(with: assetsOptions) From 32ba6eb851479a3b11ba338caafd253a31123fc8 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Fri, 13 Oct 2017 11:06:07 +0200 Subject: [PATCH 7/8] Close #4, updated docs and example app --- ExampleApp/ViewController.swift | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ExampleApp/ViewController.swift b/ExampleApp/ViewController.swift index c9ecc03..f3fb382 100644 --- a/ExampleApp/ViewController.swift +++ b/ExampleApp/ViewController.swift @@ -25,7 +25,7 @@ let cellsData: [[CellData]] = [ CellData("Disabled", #selector(ViewController.configCameraItem(indexPath:)), .indexPath, { cell, controller in cell.accessoryType = controller.cameraConfig == .disabled ? .checkmark : .none }) ], [ - CellData("Recently added (default)", #selector(ViewController.configAssetsSource(indexPath:)), .indexPath, { cell, controller in cell.accessoryType = controller.assetsSource == .recentlyAdded ? .checkmark : .none }), + CellData("Camera Roll (default)", #selector(ViewController.configAssetsSource(indexPath:)), .indexPath, { cell, controller in cell.accessoryType = controller.assetsSource == .recentlyAdded ? .checkmark : .none }), CellData("Only videos", #selector(ViewController.configAssetsSource(indexPath:)), .indexPath, { cell, controller in cell.accessoryType = controller.assetsSource == .onlyVideos ? .checkmark : .none }), CellData("Only selfies", #selector(ViewController.configAssetsSource(indexPath:)), .indexPath, { cell, controller in cell.accessoryType = controller.assetsSource == .onlySelfies ? .checkmark : .none }) ], diff --git a/README.md b/README.md index e5562d3..e2357f9 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Please refer to `CaptureSettings` public header for more information. ### Providing your own photos fetch result -By default Image Picker fetches from Photo Library 1000 recently added photos and videos. If you wish to provide your own fetch result please implement image picker controller's `assetsFetchResultBlock` block. +By default Image Picker fetches from Photo Library 1000 photos and videos from smart album `smartAlbumUserLibrary` that should represent *Camera Roll* album. If you wish to provide your own fetch result please implement image picker controller's `assetsFetchResultBlock` block. For example to fetch only live photos you can use following code snippet: From 78f7a27176ccae071fa3c306d7c491bf9daba048 Mon Sep 17 00:00:00 2001 From: Peter Stajger Date: Thu, 12 Oct 2017 14:52:33 +0200 Subject: [PATCH 8/8] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2357f9..566d4fa 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -![Image Picker: Image picker for chat applications](http://kinemakity.com/download/banner.png) +![Image Picker: Image picker for chat applications](https://user-images.githubusercontent.com/500145/31496739-deaafdc4-af5c-11e7-847c-03266262d990.png) An easy to use drop-in framework providing user interface for taking pictures and videos and pick assets from Photo Library. User interface is designed to support `inputView` "keyboard-like" presentation for conversation user interfaces. Project is written in Swift4. -![Demo](http://kinemakity.com/download/demo_1.gif) +![Demo](https://user-images.githubusercontent.com/500145/31496397-766f626e-af5b-11e7-9d6f-c0c5dda93086.gif) **Features:** - [x] presentation designed for chat apps as well as regular view controllers