Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Pod/Classes/DVGAssetPickerCollectionViewCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
@interface DVGAssetPickerCollectionViewCell : UICollectionViewCell

@property (weak, nonatomic) UIImageView *imageView;
@property (nonatomic) NSDictionary *userInfo;

@end
23 changes: 19 additions & 4 deletions Pod/Classes/DVGAssetPickerViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//

#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
@import Photos;

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, DVGAssetPickerMenuItem) {
DVGAssetPickerMenuItemPhotoLibrary,
Expand All @@ -20,18 +22,31 @@ typedef NS_ENUM(NSUInteger, DVGAssetPickerMenuItem) {
@protocol DVGAssetPickerDelegate <NSObject>

- (void)contentPickerViewController:(DVGAssetPickerViewController *)controller
didSelectAssets:(NSArray *)assets;
didSelectAssets:(NSArray<PHAsset*> *)assets;
- (void)contentPickerViewController:(DVGAssetPickerViewController *)controller
clickedMenuItem:(DVGAssetPickerMenuItem)menuItem;
- (void)contentPickerViewControllerDidCancel:(DVGAssetPickerViewController *)controller;

@end


@protocol DVGAssetPickerDataSource <NSObject>

@optional
- (NSDictionary *)contentPickerViewController:(DVGAssetPickerViewController *)controller
textAttributesForMenuItem:(DVGAssetPickerMenuItem)menuItem;

@end


@interface DVGAssetPickerViewController : UIViewController

- (instancetype)init;
- (void)cancel;
@property (nonatomic, weak) id<DVGAssetPickerDelegate> delegate;
@property (strong, nonatomic) ALAssetsLibrary *assetsLibrary;
@property (nonatomic, weak) _Nullable id<DVGAssetPickerDelegate> delegate;
@property (nonatomic, weak) _Nullable id<DVGAssetPickerDataSource> dataSource;
@property (strong, nonatomic) PHPhotoLibrary * photoLibrary;

@end

NS_ASSUME_NONNULL_END
113 changes: 61 additions & 52 deletions Pod/Classes/DVGAssetPickerViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ @interface DVGAssetPickerViewController ()
@property (weak, nonatomic) UITableView *tableView;
@property (weak, nonatomic) UICollectionView *collectionView;
@property (weak, nonatomic) NSLayoutConstraint *collectionHeightConstraint;
@property (copy, nonatomic) NSArray *assets;
@property (strong, nonatomic) NSMutableSet *selectedAssets;
@property (copy, nonatomic) PHFetchResult<PHAsset *> *assets;
@property (strong, nonatomic) NSMutableSet<PHAsset *> *selectedAssets;
@property (nonatomic) BOOL collectionViewExpanded;

@end
Expand All @@ -49,6 +49,7 @@ - (instancetype)init
self.modalPresentationStyle = UIModalPresentationCustom;
self.transitioningDelegate = self;
self.automaticallyAdjustsScrollViewInsets = YES;
self.photoLibrary = [PHPhotoLibrary sharedPhotoLibrary];
}
return self;
}
Expand All @@ -57,8 +58,6 @@ - (void)viewDidLoad
{
[super viewDidLoad];

self.assetsLibrary = [[ALAssetsLibrary alloc] init];

self.view.backgroundColor = [UIColor whiteColor];

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[self newCollectionLayout]];
Expand Down Expand Up @@ -147,38 +146,21 @@ - (void)updateViewConstraints

#pragma mark -

- (NSArray *)fetchAllAssetsSynchronously
- (PHFetchResult<PHAsset *> *)fetchAllAssetsSynchronously
{
NSMutableArray *assets = [NSMutableArray array];
dispatch_group_t dispatchGroup = dispatch_group_create();

dispatch_group_enter(dispatchGroup);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__block NSInteger maxCount = 50;
[self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) {
if (group) {
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stopAssets) {
if (result &&
[[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
[assets addObject:result];
maxCount--;
if (maxCount == 0) {
*stopAssets = *stopGroups = YES;
}
}
}];
}
else {
dispatch_group_leave(dispatchGroup);
}
} failureBlock:^(NSError *error) {
// XXX Handle error
dispatch_group_leave(dispatchGroup);
}];
});
dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER);
PHFetchResult * result = [PHAssetCollection
fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary
options:nil];
if (result.count == 0) {
return @[];
}

return assets;
PHAssetCollection * collection = result.firstObject;
PHFetchOptions * options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
options.predicate = [NSPredicate predicateWithFormat:@"mediaType == %i", PHAssetMediaTypeImage];
return [PHAsset fetchAssetsInAssetCollection:collection options:options];
}

- (void)cancel
Expand Down Expand Up @@ -257,11 +239,11 @@ - (void)collectionViewScrollToItemAtIndexPathCentered:(NSIndexPath *)indexPath
// doesn't always work correctly (for example, indexPath.row from 1 to 2).

UICollectionViewFlowLayout *layout = (id)self.collectionView.collectionViewLayout;

if ([layout isKindOfClass:[UICollectionViewFlowLayout class]] == false) {
return;
}

UIEdgeInsets inset = self.collectionView.contentInset;
UIEdgeInsets sectionInset = layout.sectionInset;
CGRect frame = [layout layoutAttributesForItemAtIndexPath:indexPath].frame;
Expand All @@ -287,34 +269,44 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
DVGAssetPickerMenuItem item = (DVGAssetPickerMenuItem)indexPath.row;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
switch ((DVGAssetPickerMenuItem)indexPath.row) {
NSString * title;

switch (item) {
case DVGAssetPickerMenuItemPhotoLibrary: {
NSInteger selectedCount = [self.selectedAssets count];
if (!self.collectionViewExpanded || selectedCount == 0) {
cell.textLabel.text = NSLocalizedString(@"Photo Library", nil);
title = NSLocalizedString(@"Photo Library", nil);
}
else if (selectedCount == 1) {
cell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Select %d Photo", nil), selectedCount];
title = [NSString stringWithFormat:NSLocalizedString(@"Select %d Photo", nil), selectedCount];
}
else {
cell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Select %d Photos", nil), selectedCount];
title = [NSString stringWithFormat:NSLocalizedString(@"Select %d Photos", nil), selectedCount];
}
break;
}

case DVGAssetPickerMenuItemCamera:
cell.textLabel.text = NSLocalizedString(@"Take Photo", nil);
title = NSLocalizedString(@"Take Photo", nil);
break;

case DVGAssetPickerMenuItemCancel:
cell.textLabel.text = NSLocalizedString(@"Cancel", nil);
title = NSLocalizedString(@"Cancel", nil);
break;
}

cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.textColor = cell.tintColor;

if ([self.dataSource respondsToSelector:@selector(contentPickerViewController:textAttributesForMenuItem:)]) {
NSDictionary* attributes = [self.dataSource contentPickerViewController:self textAttributesForMenuItem:item];
cell.textLabel.attributedText = [[NSAttributedString alloc] initWithString:title attributes:attributes];
}else {
cell.textLabel.text = title;
}

return cell;
}

Expand Down Expand Up @@ -354,11 +346,30 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ALAsset *asset = self.assets[indexPath.row];
PHAsset *asset = self.assets[indexPath.row];
DVGAssetPickerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

UIImage *thumbnail = [UIImage imageWithCGImage:[asset aspectRatioThumbnail]];
cell.imageView.image = thumbnail;

// cancel previous image fetch if the cell is being reused
if (cell.userInfo && cell.userInfo[@"request_id"]) {
PHImageRequestID requestID = [cell.userInfo[@"request_id"] intValue];
[[PHImageManager defaultManager] cancelImageRequest:requestID];
}


CGRect screenSize = [[UIScreen mainScreen] nativeBounds];
CGFloat size1D = MAX(screenSize.size.width, screenSize.size.height);
CGSize targetSize = CGSizeMake(size1D, size1D);

PHImageRequestOptions * options = [[PHImageRequestOptions alloc] init];
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
options.resizeMode = PHImageRequestOptionsResizeModeFast;
options.networkAccessAllowed = NO;

PHImageRequestID requestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
cell.imageView.image = result;
}];
cell.userInfo = @{@"request_id": @(requestID)};

return cell;
}
Expand All @@ -369,7 +380,7 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
{
UICollectionReusableView *view;
if ([kind isEqualToString:DVGAssetPickerSupplementaryKindCheckmark]) {
ALAsset *asset = self.assets[indexPath.row];
PHAsset *asset = self.assets[indexPath.row];
DVGAssetPickerCheckmarkView *checkmark = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"Checkmark" forIndexPath:indexPath];
checkmark.selected = [self.selectedAssets containsObject:asset];
view = checkmark;
Expand All @@ -382,7 +393,7 @@ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
ALAsset *asset = self.assets[indexPath.row];
PHAsset *asset = self.assets[indexPath.row];

if (!self.collectionViewExpanded) {
self.selectedAssets = [NSMutableSet setWithObject:asset];
Expand Down Expand Up @@ -426,14 +437,12 @@ - (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
ALAsset *asset = self.assets[indexPath.row];
UIImage *thumbnail = [UIImage imageWithCGImage:[asset aspectRatioThumbnail]];
PHAsset *asset = self.assets[indexPath.row];

CGFloat height = [self collectionViewHeight] - kCollectionViewPadding * 2;
CGFloat maxWidth = CGRectGetWidth(self.view.bounds) - kCollectionViewPadding * 2;
CGFloat width = (thumbnail
? thumbnail.size.width * height / thumbnail.size.height
: height);
CGFloat width = (CGFloat)asset.pixelWidth * height / (CGFloat)asset.pixelHeight;

width = MIN(maxWidth, width);
CGSize size = CGSizeMake(width, height);

Expand Down