Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/zhangao0086/DKImagePickerController

Image Picker Controller for iOS written in Swift 4 & 5.
https://github.com/zhangao0086/DKImagePickerController

picker swift

Last synced: 3 months ago
JSON representation

Image Picker Controller for iOS written in Swift 4 & 5.

Awesome Lists containing this project

README

        

DKImagePickerController
=======================

[![Build Status](https://secure.travis-ci.org/zhangao0086/DKImagePickerController.svg)](http://travis-ci.org/zhangao0086/DKImagePickerController) [![Version Status](http://img.shields.io/cocoapods/v/DKImagePickerController.png)][docsLink] [![license MIT](https://img.shields.io/cocoapods/l/DKImagePickerController.svg?style=flat)][mitLink] [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)


---

---

## Description
`DKImagePickerController` is a highly customizable, Pure-Swift library.

### Features
* Supports both single and multiple selection.
* Supports filtering albums and sorting by type.
* Supports landscape, iPad, and orientation switching.
* iCloud Support.
* Supports batch exports `PHAsset` to lcoal files.
* Inline mode Support.
* Customizable `UICollectionViewLayout`.
* Customizable `camera`, `photo gallery` and `photo editor`.
* Dark Mode Support

## Requirements
* iOS 9.0+ (Drop support for iOS 8 in 4.3.0 or above)
* ARC
* Swift 4 & 5

## Installation
### CocoaPods
#### iOS 9 and newer
DKImagePickerController is available on CocoaPods. Simply add the following line to your podfile:

```
# For latest release in cocoapods
pod 'DKImagePickerController'
```

#### For Swift 4.1
```
pod 'DKImagePickerController', :git => 'https://github.com/zhangao0086/DKImagePickerController.git', :branch => 'Swift4'
```

#### For iOS 8

```
pod 'DKImagePickerController', :git => 'https://github.com/zhangao0086/DKImagePickerController.git', :branch => 'iOS8'
```

#### Subspecs

There are 7 subspecs available now:

| Subspec | Description |
|---|---|
| Core | Required. |
| ImageDataManager | Required. The subspec provides data to `DKImagePickerController`. |
| Resource | Required. The subspec provides resource management and internationalization. |
| PhotoGallery | Optional. The subspec provides preview feature for PHAsset. |
| Camera | Optional. The subspec provides camera feature. |
| InlineCamera | Optional. The subspec should be pushed by `UINavigationController`, like `UIImagePickerController` with `UIImagePickerControllerSourceType.camera`. |
| PhotoEditor | Optional. The subspec provides basic image editing features. |

This means you can install only some of the `DKImagePickerController` modules. By default, you get all subspecs.
If you need to use your own photo editor, simply specify subspecs other than `PhotoEditor`:

```ruby
pod 'DKImagePickerController', :subspecs => ['PhotoGallery', 'Camera', 'InlineCamera']
```

More information, see [Extensions](#extensions).

### Carthage

```
github "zhangao0086/DKImagePickerController"
```

If you use Carthage to build your dependencies, make sure you have added `CropViewController.framework`, `DKCamera.framework`, `DKImagePickerController.framework`, `DKPhotoGallery.framework` and `SDWebImage.framework` to the _"Linked Frameworks and Libraries"_ section of your target, and have included them in your Carthage framework copying build phase.

## Getting Started
#### Initialization and presentation
```swift

let pickerController = DKImagePickerController()

pickerController.didSelectAssets = { (assets: [DKAsset]) in
print("didSelectAssets")
print(assets)
}

self.presentViewController(pickerController, animated: true) {}

​````

#### Configurations

​```swift
/// Use UIDelegate to Customize the picker UI.
@objc public var UIDelegate: DKImagePickerControllerBaseUIDelegate!

/// Forces deselect of previous selected image. allowSwipeToSelect will be ignored.
@objc public var singleSelect = false

/// Auto close picker on single select
@objc public var autoCloseOnSingleSelect = true

/// The maximum count of assets which the user will be able to select, a value of 0 means no limit.
@objc public var maxSelectableCount = 0

/// Photos will be tagged with the location where they are taken.
/// If true, your Info.plist should include the "Privacy - Location XXX" tag.
open var containsGPSInMetadata = false

/// Set the defaultAssetGroup to specify which album is the default asset group.
public var defaultAssetGroup: PHAssetCollectionSubtype?

/// Allow swipe to select images.
@objc public var allowSwipeToSelect: Bool = false

/// Allow select all
@objc public var allowSelectAll: Bool = false

/// A Bool value indicating whether the inline mode is enabled.
@objc public var inline: Bool = false

/// The type of picker interface to be displayed by the controller.
@objc public var assetType: DKImagePickerControllerAssetType = .allAssets

/// If sourceType is Camera will cause the assetType & maxSelectableCount & allowMultipleTypes & defaultSelectedAssets to be ignored.
@objc public var sourceType: DKImagePickerControllerSourceType = .both

/// A Bool value indicating whether allows to select photos and videos at the same time.
@objc public var allowMultipleTypes = true

/// A Bool value indicating whether to allow the picker auto-rotate the screen.
@objc public var allowsLandscape = false

/// Set the showsEmptyAlbums to specify whether or not the empty albums is shown in the picker.
@objc public var showsEmptyAlbums = true

/// A Bool value indicating whether to allow the picker shows the cancel button.
@objc public var showsCancelButton = false

/// The block is executed when the user presses the cancel button.
@objc public var didCancel: (() -> Void)?

/// The block is executed when the user presses the select button.
@objc public var didSelectAssets: ((_ assets: [DKAsset]) -> Void)?

/// The block is executed when the number of selected assets is changed.
@objc public var selectedChanged: (() -> Void)?

/// A Bool value indicating whether to allow the picker to auto-export the selected assets to the specified directory when done is called.
/// picker will creating a default exporter if exportsWhenCompleted is true and the exporter is nil.
@objc public var exportsWhenCompleted = false

@objc public var exporter: DKImageAssetExporter?

/// Indicates the status of the exporter.
@objc public private(set) var exportStatus = DKImagePickerControllerExportStatus.none {
willSet {
if self.exportStatus != newValue {
self.willChangeValue(forKey: #keyPath(DKImagePickerController.exportStatus))
}
}

didSet {
if self.exportStatus != oldValue {
self.didChangeValue(forKey: #keyPath(DKImagePickerController.exportStatus))

self.exportStatusChanged?(self.exportStatus)
}
}
}

/// The block is executed when the exportStatus is changed.
@objc public var exportStatusChanged: ((DKImagePickerControllerExportStatus) -> Void)?

/// The object that acts as the data source of the picker.
@objc public private(set) lazy var groupDataManager: DKImageGroupDataManager

```

## Inline Mode

```swift
let groupDataManagerConfiguration = DKImageGroupDataManagerConfiguration()
groupDataManagerConfiguration.fetchLimit = 10
groupDataManagerConfiguration.assetGroupTypes = [.smartAlbumUserLibrary]

let groupDataManager = DKImageGroupDataManager(configuration: groupDataManagerConfiguration)

self.pickerController = DKImagePickerController(groupDataManager: groupDataManager)
pickerController.inline = true
pickerController.UIDelegate = CustomInlineLayoutUIDelegate(imagePickerController: pickerController)
pickerController.assetType = .allPhotos
pickerController.sourceType = .photo

let pickerView = self.pickerController.view!
pickerView.frame = CGRect(x: 0, y: 170, width: self.view.bounds.width, height: 200)
self.view.addSubview(pickerView)
```

## Customizable UI

For example, see [CustomUIDelegate](https://github.com/zhangao0086/DKImagePickerController/tree/develop/Example/DKImagePickerControllerDemo/CustomUIDelegate).

## Customizable Layout

For example, see [CustomLayoutUIDelegate](https://github.com/zhangao0086/DKImagePickerController/tree/develop/Example/DKImagePickerControllerDemo/CustomLayoutUIDelegate).

### Conforms UIAppearance protocol

You can easily customize the appearance of the navigation bar using the appearance proxy.
```swift
UINavigationBar.appearance().titleTextAttributes = [
NSFontAttributeName : UIFont(name: "Optima-BoldItalic", size: 21)!,
NSForegroundColorAttributeName : UIColor.redColor()
]
```

## Exporting to file

By default, the picker uses a singleton object of `DKImageAssetExporter` to export `DKAsset` to local files.

```swift
/*
Configuration options for a DKImageAssetExporter. When an exporter is created,
a copy of the configuration object is made - you cannot modify the configuration
of an exporter after it has been created.
*/
@objc
public class DKImageAssetExporterConfiguration: NSObject, NSCopying {

@objc public var imageExportPreset = DKImageExportPresent.compatible

/// videoExportPreset can be used to specify the transcoding quality for videos (via a AVAssetExportPreset* string).
@objc public var videoExportPreset = AVAssetExportPresetHighestQuality

#if swift(>=4.0)
@objc public var avOutputFileType = AVFileType.mov
#else
@objc public var avOutputFileType = AVFileTypeQuickTimeMovie
#endif

@objc public var exportDirectory = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("DKImageAssetExporter")
}

/*
A DKImageAssetExporter object exports DKAsset(PHAsset) from album (or iCloud) to the app's tmp directory (by default).
It automatically deletes the exported directories when it receives a UIApplicationWillTerminate notification.
*/
@objc
open class DKImageAssetExporter: DKBaseManager {

/// This method starts an asynchronous export operation of a batch of asset.
@discardableResult
@objc public func exportAssetsAsynchronously(assets: [DKAsset], completion: ((_ info: [AnyHashable : Any]) -> Void)?) -> DKImageAssetExportRequestID
}
```

This exporter can automatically convert HEIF to JPEG:

```swift
@objc
public enum DKImageExportPresent: Int {
case
compatible, // A preset for converting HEIF formatted images to JPEG.
current // A preset for passing image data as-is to the client.
}
```

You also can observe the export progress of each asset:

```swift
@objc
public protocol DKImageAssetExporterObserver {

@objc optional func exporterWillBeginExporting(exporter: DKImageAssetExporter, asset: DKAsset)

/// The progress can be obtained from the DKAsset.
@objc optional func exporterDidUpdateProgress(exporter: DKImageAssetExporter, asset: DKAsset)

/// When the asset's error is not nil, it indicates that an error occurred while exporting.
@objc optional func exporterDidEndExporting(exporter: DKImageAssetExporter, asset: DKAsset)
}

extension DKAsset {

/// The exported file will be placed in this location.
/// All exported files can be automatically cleaned by the DKImageAssetDiskPurger when appropriate.
@objc public var localTemporaryPath: URL?

@objc public var fileName: String?

/// Indicates the file's size in bytes.
@objc public var fileSize: UInt

/// If you export an asset whose data is not on the local device, and you have enabled downloading with the isNetworkAccessAllowed property, the progress indicates the progress of the download. A value of 0.0 indicates that the download has just started, and a value of 1.0 indicates the download is complete.
@objc public var progress: Double

/// Describes the error that occurred if the export has failed or been cancelled.
@objc public var error: Error?
}
```

For example, see `Export automatically` and `Export manually`.

## Extensions
This picker uses `DKImageExtensionController` manages all extensions, you can register it with a `DKImageBaseExtension` and a specified `DKImageExtensionType` to customize `camera`, `photo gallery` and `photo editor`:

```swift
/// Registers an extension for the specified type.
public class func registerExtension(extensionClass: DKImageBaseExtension.Type, for type: DKImageExtensionType)

public class func unregisterExtension(for type: DKImageExtensionType)
```

The `perform` function will be called with a dictionary providing current context information when an extension is triggered:

```swift
/// Starts the extension.
func perform(with extraInfo: [AnyHashable: Any])

/// Completes the extension.
func finish()
```

The `extraInfo` will provide different information for different `DKImageExtensionType`:

##### Camera

```swift
let didFinishCapturingImage = extraInfo["didFinishCapturingImage"] as? ((UIImage, [AnyHashable : Any]?) -> Void)
let didCancel = extraInfo["didCancel"] as? (() -> Void)
```

For a custom camera example, see [CustomCameraExtension](https://github.com/zhangao0086/DKImagePickerController/tree/develop/Example/DKImagePickerControllerDemo/CustomCamera).

##### InlineCamera
The `extraInfo` is the same as for `Camera`.

##### Photo Gallery

```swift
let groupId = extraInfo["groupId"] as? String
let presentationIndex = extraInfo["presentationIndex"] as? Int
let presentingFromImageView = extraInfo["presentingFromImageView"] as? UIImageView
```

##### Photo Editor

```swift
let image = extraInfo["image"] as? UIImage
let didFinishEditing = extraInfo["didFinishEditing"] as? ((UIImage, [AnyHashable : Any]?) -> Void)
let metadata = extraInfo["metadata"] as? [AnyHashable : Any]
```

## How to use in Objective-C

#### If you use [CocoaPods](http://cocoapods.org/)

* Add the following two lines into your `Podfile`:

```
pod 'DKImagePickerController'
use_frameworks!
```
* Import the library into your Objective-C file:

```objective-c
#import
```

#### If you use it directly in your project

> See also:[Swift and Objective-C in the Same Project](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html)

* Drag and drop the [DKCamera][DKCamera], `DKImageManager` and `DKImagePickerController` to your project
* Import the library into your Objective-C file:

```objective-c
#import "YourProductModuleName-Swift.h"
```

---
then you can:

```objective-c
DKImagePickerController *pickerController = [DKImagePickerController new];

[pickerController setDidSelectAssets:^(NSArray * __nonnull assets) {
NSLog(@"didSelectAssets");
}];

[self presentViewController:pickerController animated:YES completion:nil];
```

## Localization
The default supported languages:

> en, es, da, de, fr, hu, ja, ko, nb-NO, pt_BR, ru, tr, ur, vi, ar, it, zh-Hans, zh-Hant

You can also add a hook to return your own localized string:

```swift
DKImagePickerControllerResource.customLocalizationBlock = { title in
if title == "picker.select.title" {
return "Test(%@)"
} else {
return nil
}
}
```

or images:

```swift
DKImagePickerControllerResource.customImageBlock = { imageName in
if imageName == "camera" {
return DKImagePickerControllerResource.photoGalleryCheckedImage()
} else {
return nil
}
}
```

## Contributing to this project
If you have feature requests or bug reports, feel free to help out by sending pull requests or by creating new issues.

## License
DKImagePickerController is released under the MIT license. See LICENSE for details.

[mitLink]:http://opensource.org/licenses/MIT
[docsLink]:http://cocoadocs.org/docsets/DKImagePickerController
[DKCamera]:https://github.com/zhangao0086/DKCamera