在APP中点击照片,都会显示出大图,然后在大图的上面会有个保存照片的按钮,照片直接保存到了系统的【相机胶卷】相册中,但是因为公司产品的需要,我们需要创建和APP同名的相册保存在【自定义相册】里面,这也就是分应用存储,因为用户可能从QQ,微信,微博分别存储,下次用户想找某个应用的图片,直接点开该应用相册即可,提高用户体验。
注意:
【自定义相册】里面的图片来源于【相机胶卷】相册中,即:【相机胶卷】引用【自定义相册】, 如果用户删掉【相机胶卷】里面的图片, 那么【自定义相册】重的图片也会删掉。但是,如果用户删掉【自定义相册】里面的图片, 那么【相机胶卷】中依然有该图片。
开发步骤:
- 1.先保存图片到【相机胶卷】(不能直接保存到自定义相册中)
- 2.拥有一个【自定义相册】
- 3.将刚才保存到【相机胶卷】里面的图片引用到【自定义相册】
方法1:用C语言函数实现
将图片保存到系统的相册中,只需要下面两句代码就搞定了
//参数1:图片对象
//参数2:成功方法绑定的target
//参数3:成功后调用方法
//参数4:需要传递信息(成功后调用方法的参数)
UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
#pragma mark -- <保存到相册>
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSString *msg = nil ;
if(error){
msg = @"保存图片失败" ;
}else{
msg = @"保存图片成功" ;
}
}
注意:UIImageWriteToSavedPhotosAlbum方法必须实现图1
的代理方法,否则会崩溃。
界面效果如下:界面图
效果图.png
方法2:使用Photos框架实现
2.1 Photos01-基本认识
PHAsset : 一个PHAsset对象就代表相册中的一张图片或者一个视频
PHAssetCollection : 一个PHAssetCollection 对象就代表一个相册
如果我们想保存图片到【相机胶卷】,首先要保证添加一个新的PHAsset对象,那么如何操作这些对象呢?无非是对这些对象进行增删改查。
PHAsset
一个PHAsset对象就代表相册中的一张图片或者一个视频
增删改 PHAssetChangeRequest 包括图片/视频相关的改动操作查 [PHAsset fetchAssets...];
PHAssetCollection
一个PHAssetCollection 对象就代表一个相册
增删改 PHAssetCollectionChangeRequest 包括相册相关的所有改动操作
查
[PHAssetCollection fetchAssetCollectionsContainingAsset:...];
2.2 Photos02-保存图片到相机胶卷
//保存图片到【相机胶卷】
/// 异步执行修改操作
[[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (error) {
NSLog(@"%@",@"保存失败");
} else {
NSLog(@"%@",@"保存成功");
}
}];
效果如图2 图3所示
2.png 3.png
Tips:
如果直接使用 [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; 则会出现如下的崩溃信息
reason: 'This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]'
结论:凡是涉及增删改的操作,均需要放在performChanges
里面执行。
[[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
// 这里执行操作
} completionHandler:^(BOOL success, NSError * _Nullable error) {
}];
2.3 Photos03-创建新的相册
NSError *error = nil;
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
//获取app名字
NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString*)kCFBundleNameKey];
//创建一个【自定义相册】
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
} error:&error];
效果如图4:
4.png
Tips:如果我们一直点击保存图片按钮,则会出现重复创建多个相册的问题:
如图5所示
5.png接着我们来解决这个问题。
2.4 Photos04-查询相册
NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString*)kCFBundleNameKey];
//查询所有【自定义相册】
PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
PHAssetCollection *createCollection = nil;
for (PHAssetCollection *collection in collections) {
if ([collection.localizedTitle isEqualToString:title]) {
createCollection = collection;
break;
}
}
if (createCollection == nil) {
//当前对应的app相册没有被创建
//创建一个【自定义相册】
NSError *error = nil;
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
//创建一个【自定义相册】
[PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
} error:&error];
}
输出结果:
此时,无论你点击多少次,均只会创建一个与APP同名的相册。
Tips: 如果我们想把图片保存到【自定义相册】里面的话,必须拿到相册对象,但是细心地你此时可能会发现,如果是第一次创建相册(即:相册中没有与APP同名的相册),
createCollection
对象会为nil,所以我们还需要优化创建【自定义相册】的代码。
核心代码:
if (createCollection == nil) {
//当前对应的app相册没有被创建
//创建一个【自定义相册】
NSError *error = nil;
__block NSString *createCollectionID = nil;
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
//创建一个【自定义相册】
createCollectionID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier;
} error:&error];
createCollection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createCollectionID] options:nil].firstObject;
}
NSLog(@"%@",createCollection);
输出结果:
2018-08-12 12:31:59.198751+0800 SavePhotoDemo[971:36240] <PHAssetCollection: 0x7fde6dc33960> 7C7FBA58-54AA-4320-9B2A-593BB75428FB/L0/040, title:"SavePhotoDemo", subtitle:"(null)" assetCollectionType=1/2
2.5 Photos05-保存图片到自定义相册
我们创建完相册之后,需要将【相机胶卷】中的图片放到【自定义相册】里面去。
核心代码如下:
// 1.先保存图片到【相机胶卷】
/// 同步执行修改操作
NSError *error = nil;
__block PHObjectPlaceholder *placeholder = nil;
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
placeholder = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset;
} error:&error];
if (error) {
NSLog(@"保存失败");
return;
}
// 2.拥有一个【自定义相册】
PHAssetCollection * assetCollection = self.createCollection;
if (assetCollection == nil) {
NSLog(@"创建相册失败");
}
// 3.将刚才保存到【相机胶卷】里面的图片引用到【自定义相册】
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
PHAssetCollectionChangeRequest *requtes = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
[requtes addAssets:@[placeholder]];
} error:&error];
if (error) {
NSLog(@"保存图片失败");
} else {
NSLog(@"保存图片成功");
}
此时,我们点击保存图片到新建相册~
按钮的时候,改图片变被保存到【相机胶卷】和【自定义相册】里面了。
如图6所示
但是,此时你会发现,每保存新的图片,自定义相册中均会添加到后面,那么如何把每次新添加的图片前置呢?我们发现【相机胶卷】中每次新的图片均会作为封面,系统自带的这个比较智能,如图图7所示
7.png
所以修改添加图片到相册的代码
// 3.将刚才保存到【相机胶卷】里面的图片引用到【自定义相册】
[[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
PHAssetCollectionChangeRequest *requtes = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
[requtes insertAssets:@[placeholder] atIndexes:[NSIndexSet indexSetWithIndex:0]];
} error:&error];
此时,【自定义相册】中新添加的图片便会作为相册的封面了,效果如图8所示。
8.png
网友评论