AssetsPickerViewController

Customizable assets picker controller that supports selecting multiple photos and videos, fully written in Swift.

Comment

AssetsPickerViewController acts like Photos App in iOS.

If you found any bugs - even in develop branch, do not hesitate raise an issue for it.

Any advice, suggestions, and pull requests for new feature will be greatly appreciated.

Screenshots

iOS friendly UI for Album & Asset

albums_portrait
photos_portrait

iPad Support

ipad_landscape

Keeps focusing indexes during orientation change.

photos_landscape

Handles empty or no permisson cases.

no_photos
no_permission

Customizable Album & Asset Layout

customize_album
customize_asset

3D Touch to Preview

3d_touch

Features Done

  • iOS friendly UI for album & photo controllers

  • select album

  • select multiple photos and videos

  • realtime synchronization for library change in albums & photos

  • option to show/hide empty albums

  • option to show/hide "Hidden" album

  • customizable album cell

  • customizable album sorting by PHFetchOptions or filter block

  • customizable album filtering by PHFetchOptions or filter block

  • customizable asset cell

  • customizable asset sorting by PHFetchOptions

  • customizable asset filtering by PHFetchOptions

  • iPad support

  • force(3D) touch to preview - (still, live photo, and video)

  • support many languages(German, French, Spanish, Chinese, Japanese, Arabic, Spanish, Korean, Indonesian, Russian, Turkish, Italian, etc)

  • set selected assets before present picker controller

Features To-do

  • single select mode with crop

Basic Usage

To run the example project, clone the repo, and run pod install from the Example directory first.

// to show
let picker = AssetsPickerViewController()
picker.pickerDelegate = self
present(picker, animated: true, completion: nil)

// to handle
extension SimpleExampleController: AssetsPickerViewControllerDelegate {
    
    func assetsPickerCannotAccessPhotoLibrary(controller: AssetsPickerViewController) {}
    func assetsPickerDidCancel(controller: AssetsPickerViewController) {}
    func assetsPicker(controller: AssetsPickerViewController, selected assets: [PHAsset]) {
        // do your job with selected assets
    }
    func assetsPicker(controller: AssetsPickerViewController, shouldSelect asset: PHAsset, at indexPath: IndexPath) -> Bool {
        return true
    }
    func assetsPicker(controller: AssetsPickerViewController, didSelect asset: PHAsset, at indexPath: IndexPath) {}
    func assetsPicker(controller: AssetsPickerViewController, shouldDeselect asset: PHAsset, at indexPath: IndexPath) -> Bool {
        return true
    }
    func assetsPicker(controller: AssetsPickerViewController, didDeselect asset: PHAsset, at indexPath: IndexPath) {}
}
Swift

Bonus

Basic

To hide empty albums,

pickerConfig.albumIsShowEmptyAlbum = false
Swift

To show "Hidden" albums,

pickerConfig.albumIsShowHiddenAlbum = true
Swift

To set pre-selected assets before present picker,

pickerConfig.selectedAssets = self.assets
Swift

To limit selected assets count,

func assetsPicker(controller: AssetsPickerViewController, shouldSelect asset: PHAsset, at indexPath: IndexPath) -> Bool {   
    if controller.selectedAssets.count > 3 {
        // do your job here
        return false
    }
    return true
}
Swift

To enable single image select mode, deselect all items when the limit has reached,

func assetsPicker(controller: AssetsPickerViewController, shouldSelect asset: PHAsset, at indexPath: IndexPath) -> Bool {   
    if controller.selectedAssets.count > 0 {
        controller.photoViewController.deselectAll()
    }
    return true
}
Swift

Appearence

To apply custom album cell,

pickerConfig.albumCellType = CustomAlbumCell.classForCoder()
// and implement your own UICollectionViewCell which conforms to AssetsAlbumCellProtocol
Swift

To apply custom asset cell,

pickerConfig.assetCellType = CustomAssetCell.classForCoder()
// and implement your own UICollectionViewCell which conforms to AssetsPhotoCellProtocol
Swift

Sorting

To sort albums by PHFetchOptions,

let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(key: "estimatedAssetCount", ascending: true)]
        
pickerConfig.albumFetchOptions = [
    .smartAlbum: options
]
Swift

To sort by block for a certain reason,

pickerConfig.albumComparator = { (albumType, leftEntry, rightEntry) -> Bool in
    // return: Is leftEntry ordered before the rightEntry?
    switch albumType {
    case .smartAlbum:
        return leftEntry.album.assetCollectionSubtype.rawValue < rightEntry.album.assetCollectionSubtype.rawValue
    case .album:
        return leftEntry.result.count < rightEntry.result.count     // ascending order by asset count
    case .moment:
        return true
    }
}
Swift

To sort assets by PHFetchOptions,

let options = PHFetchOptions()
options.sortDescriptors = [
    NSSortDescriptor(key: "pixelWidth", ascending: true),
    NSSortDescriptor(key: "pixelHeight", ascending: true)
]

pickerConfig.assetFetchOptions = [
    .smartAlbum: options
]
Swift

Filtering

To filter albums by PHFetchOptions,

let options = PHFetchOptions()
options.predicate = NSPredicate(format: "estimatedAssetCount = 0")
pickerConfig.albumFetchOptions = [.smartAlbum: options]
Swift

To filter albums by block for a certain reason,

// return true to include, false to discard.
let smartAlbumFilter: ((PHAssetCollection, PHFetchResult<PHAsset>) -> Bool) = { (album, fetchResult) in
    // filter by album object
    if album.assetCollectionSubtype == .smartAlbumBursts { return false }
    if album.assetCollectionSubtype == .smartAlbumTimelapses { return false }
    if album.assetCollectionSubtype == .smartAlbumFavorites { return false }
            
    // filter by fetch result
    if fetchResult.count > 50 {
        return true     // only shows albums that contains more than 50 assets
    } else {
        return false    //
    }
}
pickerConfig.albumFilter = [
    .smartAlbum: smartAlbumFilter
]
Swift

To filter assets by PHFetchOptions,

let options = PHFetchOptions()
options.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.video.rawValue)
options.sortDescriptors = [NSSortDescriptor(key: "duration", ascending: true)]
        
pickerConfig.assetFetchOptions = [
    .smartAlbum: options,
    .album: options
]
Swift

Requirements & Dependency

Xcode9, Swift 4, iOS 9.0

Uses PureLayout for creating UI inside library. Thanks to PureLayout development team for doing such a beautiful job.

Installation

AssetsPickerViewController is available through CocoaPods. To install
it, simply add the following line to your Podfile:

pod 'AssetsPickerViewController', '~> 2.0'
Ruby

Swift 3 is not supported anymore.

GitHub

Powerfully Customizable - Multiple Photo & Video Picker ControllerRead More

Latest commit to the master branch on 9-21-2022
Download as zip