這兩天產(chǎn)品說(shuō)我用系統(tǒng)的
UIImagePickerController
界面UI很丑寥假,迫不得已下就選擇了自定義一個(gè)照片選擇器笋除。實(shí)現(xiàn)效果如下圖:
demo中3張效果圖.png
實(shí)現(xiàn)步驟
具體實(shí)現(xiàn)就兩個(gè)步驟:
1.用系統(tǒng)的<Photos/Photos.h>
框架異步獲取到相冊(cè)中的所有圖片(包括原圖和縮略圖)届腐,然后用collectionview
進(jìn)行展示縮略圖苛茂。
2.再對(duì)獲取到相冊(cè)圖片的原圖進(jìn)行裁剪,分圓形裁剪和方形裁剪胧后。裁剪框路徑使用貝塞爾曲線分別設(shè)置的路徑
//設(shè)置圓形路徑舍败。
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
//設(shè)置帶有圓角的矩形路徑
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius ```
######具體代碼
寫(xiě)了個(gè)```UIImage+Extension.h```的分類谤祖,異步并發(fā)獲取到所有圖片
/**
獲取系統(tǒng)相冊(cè)中所有的縮略圖 和原圖
縮略圖 尺寸 大約 {32.5闪彼,60} (allSmallImageArray 回調(diào)獲取到的縮略圖 圖片數(shù)組)
原圖 尺寸 大約 屏幕等大 (allOriginalImageArray 回調(diào)獲取到的大圖 圖片數(shù)組)
*/
- (void)async_getLibraryPhoto:(void(^)(NSArray <UIImage *> *allSmallImageArray))smallImageCallBack
allOriginalImageCallBack:(void(^)(NSArray <UIImage *> *allOriginalImageArray))allOriginalImageCallBack
{
static UIImage *image;image = [UIImage new];
dispatch_queue_t concurrencyQueue = dispatch_queue_create("getLibiaryAllImage-queue",
DISPATCH_QUEUE_CONCURRENT);
// task 1 : 獲得相冊(cè)中所有 縮略圖
dispatch_async(concurrencyQueue, ^{
NSMutableArray *smallPhotoArray = [NSMutableArray array];
[smallPhotoArray addObjectsFromArray:[UIImage getImageWithScaleImage:image isOriginalPhoto:NO]];
dispatch_async(dispatch_get_main_queue(), ^{
if (smallImageCallBack) {
smallImageCallBack([smallPhotoArray copy]);
}
});
});
// task 2 : 獲得相冊(cè)中所有 原圖
dispatch_async(concurrencyQueue, ^{
NSMutableArray *allOriginalPhotoArray = [NSMutableArray array];
[allOriginalPhotoArray addObjectsFromArray:[UIImage getImageWithScaleImage:image isOriginalPhoto:YES]];
dispatch_async(dispatch_get_main_queue(), ^{
if (allOriginalImageCallBack) {
allOriginalImageCallBack([allOriginalPhotoArray copy]);
}
});
});
} - (NSArray <UIImage *> *)getImageWithScaleImage:(UIImage *)image isOriginalPhoto:(BOOL)isOriginalPhoto
{
NSMutableArray *photoArray = [NSMutableArray array];
// 獲得所有的自定義相冊(cè)
PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
// 遍歷所有的自定義相冊(cè)
for (PHAssetCollection *assetCollection in assetCollections) {
[photoArray addObjectsFromArray:[image enumerateAssetsInAssetCollection:assetCollection original:isOriginalPhoto]];
}
// 獲得相機(jī)膠卷相冊(cè)
PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
[photoArray addObjectsFromArray:[image enumerateAssetsInAssetCollection:cameraRoll original:isOriginalPhoto]];
return photoArray;
}
/**
- 遍歷相簿中的所有圖片
- @param assetCollection 相冊(cè)
- @param original 是否需要原圖
*/
- (NSArray <UIImage *> *)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollection original:(BOOL)original
{
NSMutableArray *array = [NSMutableArray array];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
// 同步獲得圖片
options.synchronous = YES;
// 獲得某個(gè)相簿中的所有PHAsset對(duì)象
PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
for (PHAsset *asset in assets) {
CGSize size = original ? CGSizeMake(asset.pixelWidth, asset.pixelHeight) : CGSizeZero;
// 從asset中獲得圖片
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
[array addObject:result];
}];
}
return array;
} ```
然后自定義一個(gè)照片控制器繼承于UICollectionViewController
甜孤,設(shè)置代理回調(diào)方法和初始化方法
HPPhotoPickerController.h
#import <UIKit/UIKit.h>
@class HPPhotoPickerController;
@protocol HPPhotoPickerControllerDelegate <NSObject>
- (void)imagePickerController:(HPPhotoPickerController *)picker didFinishPickingWithImage:(UIImage *)image;
@end
@interface HPPhotoPickerController : UICollectionViewController
@property (nonatomic ,weak) id <HPPhotoPickerControllerDelegate> delegate;
/**
照片 選擇控制器 初始化 方法
@param delegate 控制器代理
@param isOvalClip 裁剪方式 YES : 正方形裁剪 NO :圓形裁剪
@param layout 控制器 layout
@return self
*/
- (instancetype)initWithDelegate:(id)delegate
isOvalClip:(BOOL)isOvalClip
flowLayout:(UICollectionViewFlowLayout *)layout;
@end ```
```HPPhotoPickerController.m```獲取圖片然后去下個(gè)界面進(jìn)行裁剪
#import "HPPhotoPickerController.h"
#import "UIImage+Extension.h"
#import "HPPhotoPickerDetailController.h"
@class HPPickerImageViewCell;
@interface HPPhotoPickerController ()<UICollectionViewDelegateFlowLayout>
{
BOOL _isOvalClip;
}
@property (nonatomic ,strong) NSMutableArray *smallphotoArray;
@property (nonatomic ,strong) NSMutableArray *bigPhotoArray;
@end
@implementation HPPhotoPickerController
static NSString * const reuseIdentifier = @"Cell";
- (void)getData
{
[UIImage async_getLibraryPhoto:^(NSArray<UIImage *> *allSmallImageArray) {
NSLog(@"***小**%ld",allSmallImageArray.count);
[self.smallphotoArray addObjectsFromArray:allSmallImageArray];
[self.collectionView reloadData];
} allOriginalImageCallBack:^(NSArray<UIImage *> *allOriginalImageArray) {
NSLog(@"***大**%ld",allOriginalImageArray.count);
[self.bigPhotoArray addObjectsFromArray:allOriginalImageArray];
}];
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.smallphotoArray.count > 0) {
return self.smallphotoArray.count;
}
return 0;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
HPPickerImageViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.photo.image = self.smallphotoArray[indexPath.row];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//判斷大于0,是做安全處理,大圖加載慢缴川,防止還沒(méi)加載完畢就push囱稽,造成數(shù)據(jù)傳空
if (self.bigPhotoArray.count > 0) {
HPPhotoPickerDetailController *detailVC = [[HPPhotoPickerDetailController alloc]initWithImage:self.bigPhotoArray[indexPath.row] delegate:self];
detailVC.ovalClip = _isOvalClip;
[self.navigationController pushViewController:detailVC animated:YES];
}
} ```
裁剪圖片的控制器是參照這位同學(xué)寫(xiě)的[iOS實(shí)現(xiàn)頭像裁剪(方或圓)功能二跋,支持縮放拖曳](http://www.reibang.com/p/d9ca82c1834c)
[這是demo地址,大家加油流昏,開(kāi)源使人進(jìn)步扎即。。况凉。](https://github.com/leijianmin/PhotoPickerController)