Demo:https://github.com/Gamin-fzym/GACustomPhotoSelector
本文的产生,因今年夏季被面试时有被问到的一个问题。有没有自定义过相片选择器?于是抽空查资料写一个简单demo放在这里。
内容:
1.写了一个“自定义图片选择器”。
2.获取到图片后为了剪切图片使用了工具“PureCamera”。
3.将编辑后的图片保存到自定义相册。
4.最后为自定义图片选择器添加了多选功能。
demo示意图:
首页(HomeViewController)
首页示意图:
#import "HomeViewController.h"
#import
#import "TOCropViewController.h"
#import "PureCamera.h"
#import "ListViewController.h"
#import "SVProgressHUD.h"
#import "GACustomSelectPIC.h"
#import "GACustomSelectProtocol.h"
#import "GAPublicMethod.h"
@interface HomeViewController ()
@property (weak, nonatomic) IBOutlet UIButton *photoBut;
@property (strong, nonatomic) UIImage *displayImg;
@property (strong, nonatomic) UIImagePickerController *ipc;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@end
@implementation HomeViewController
- (void)entryListVCWith:(UIImage *)image {
_displayImg = image;
[_photoBut setBackgroundImage:image forState:UIControlStateNormal];
ListViewController *lVC = [[ListViewController alloc] initWithNibName:@"ListViewController" bundle:nil];
lVC.img = image;
[self.navigationController pushViewController:lVC animated:YES];
}
- (IBAction)tapPhotoAction:(id)sender {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self selectTakePhoto];
}];
[alert addAction:cameraAction];
UIAlertAction *albumAction = [UIAlertAction actionWithTitle:@"从相册中选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self selectAlbum];
}];
[alert addAction:albumAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)selectTakePhoto {
// 引用相机
PureCamera *homec = [[PureCamera alloc] init];
__weak typeof(self)myself = self;
homec.fininshcapture = ^(UIImage *image){
if (image) {
[myself entryListVCWith:image];
}
} ;
[self presentViewController:homec animated:NO completion:^{}];
}
- (void)selectAlbum {
if (!self.ipc) {
self.ipc = [[UIImagePickerController alloc] init];
self.ipc.delegate = self;
self.ipc.navigationBar.translucent = NO;
self.ipc.edgesForExtendedLayout = UIRectEdgeNone;
//self.ipc.allowsEditing = YES;
}
self.ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:self.ipc animated:YES completion:^{}];
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// 从info取出此时摄像头的媒体类型
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
// 获取照片的原图
UIImage *original = [info objectForKey:UIImagePickerControllerOriginalImage];
// 引用图片裁剪页
TOCropViewController *cropController = [[TOCropViewController alloc] initWithImage:original aspectRatioStle:TOCropViewControllerAspectRatioOriginal];
cropController.delegate = self;
// [self pushViewController:cropController animated:YES];
[picker presentViewController:cropController animated:YES completion:nil];
} else {
[picker dismissViewControllerAnimated:YES completion:^{}];
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:^{}];
}
#pragma mark - TOCropViewControllerDelegate
- (void)cropViewController:(TOCropViewController *)cropViewController didCropToImage:(UIImage *)image withRect:(CGRect)cropRect angle:(NSInteger)angle {
if (image) {
//[cropViewController.navigationController popViewControllerAnimated:YES];
[cropViewController dismissViewControllerAnimated:YES completion:nil];
[_ipc dismissViewControllerAnimated:NO completion:^{}];
[self entryListVCWith:image];
}
}
- (void)cropViewController:(nonnull TOCropViewController *)cropViewController didFinishCancelled:(BOOL)cancelled {
[cropViewController dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - 自定义图片选择器
- (IBAction)customSelectPicture:(id)sender {
GACustomSelectPIC *custom = [[GACustomSelectPIC alloc] initWithNibName:@"GACustomSelectPIC" bundle:nil];
custom.delegate = self;
custom.tempLimitMax = 5;
[self.navigationController pushViewController:custom animated:YES];
}
#pragma mark - GACustomSelectProtocol
- (void)customSelectAssets:(NSMutableArray *)assets {
NSArray *subViews = [self.scrollView subviews];
for (int i = 0 ; i < subViews.count ; i ++) {
UIView *tempView = [subViews objectAtIndex:i];
[tempView removeFromSuperview];
}
float width = self.scrollView.bounds.size.height;
NSMutableArray *selectImages = [NSMutableArray new];
for (int i = 0 ; i < assets.count ; i ++) {
id tempAsset = [assets objectAtIndex:i];
[self fetchImageWithAsset:tempAsset imageBlock:^(UIImage * _Nonnull image) {
[selectImages addObject:image];
//NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
UIImageView *tempIV = [UIImageView new];
tempIV.frame = CGRectMake(i*width, 0, width, width);
tempIV.image = image;
tempIV.contentMode = UIViewContentModeScaleAspectFill;
[tempIV.layer setMasksToBounds:YES];
[self.scrollView addSubview:tempIV];
[self.scrollView setContentSize:CGSizeMake(CGRectGetMaxX(tempIV.frame), width)];
}];
}
}
@end
列表页(ListViewController)
展示剪切后的图片,保存图片到自定义的相册
展示剪切图片示意图:
保存图片到自定义相册:
#import "ListViewController.h"
#import
#import "SVProgressHUD.h"
@interface ListViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *playIV;
@end
@implementation ListViewController
- (IBAction)savePictureAction:(id)sender {
/**
获取用户授权状态
typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
PHAuthorizationStatusNotDetermined = 0, // 不确定
PHAuthorizationStatusRestricted, // 家长控制,拒绝
PHAuthorizationStatusDenied, // 拒绝
PHAuthorizationStatusAuthorized // 授权
} PHOTOS_AVAILABLE_IOS_TVOS_OSX(8_0, 10_0, 10_13);
*/
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) {
// 如果状态是不确定的话,block中的内容会等到授权完成再调用
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
[self savePhoto];
}
}];
} else if (status == PHAuthorizationStatusAuthorized) {
[self savePhoto];
} else {
// 提示用户去打开授权
[SVProgressHUD showInfoWithStatus:@"进入设置界面->找到当前应用->打开允许访问相册开关"];
}
}
#pragma mark - 该方法获取在图库中是否已经创建该App的相册
// 该方法的作用,获取系统中所有的相册进行遍历,若是已有该相册则返回该相册,若是没有该相册则返回nil,参数为需要创建的相册名称
- (PHAssetCollection *)fetchAssetColletion:(NSString *)albumTitle {
// 获取所有的相册
PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
// 遍历相册数组
for (PHAssetCollection *assetCollection in result) {
if ([assetCollection.localizedTitle isEqualToString:albumTitle]) {
return assetCollection;
}
}
return nil;
}
#pragma mark - 保存图片的方法
- (void)savePhoto {
// 修改系统相册用PHPhotoLibrary单例
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 调用判断是否已有该名称相册
PHAssetCollection *assetCollection = [self fetchAssetColletion:@"测试相册"];
// 创建一个操作图库的对象
PHAssetCollectionChangeRequest *assetCollectionChangeRequest;
if (assetCollection) {
// 已有相册则获取该相册
assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
} else {
// 没有该相册则创建自定义相册
assetCollectionChangeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"测试相册"];
}
// 保存你需要保存的图片到自定义相册
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:self.playIV.image];
// 这个block是异步执行的,使用占位图片先为图片分配一个内存,等到有图片的时候,再对内存进行赋值
PHObjectPlaceholder *placeholder = [assetChangeRequest placeholderForCreatedAsset];
[assetCollectionChangeRequest addAssets:@[placeholder]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (error) {
[SVProgressHUD showErrorWithStatus:@"保存失败"];
} else {
[SVProgressHUD showSuccessWithStatus:@"保存成功"];
}
}];
}
@end
自定义图片选择器(GACustomSelectPIC)
代码太多,放上效果图,详见demo...
自定义图片选择器相册列表:
自定义图片选择器图组列表:
TO:
PureCamera
iOS 自定义图片选择器 1 - PhotoKit
iOS中怎么存储照片到自定义相册