iOS 自定义相册

来源:互联网 发布:文件数据库 编辑:程序博客网 时间:2024/06/05 14:25

目录(?)[-]

  1. One    将图片保存到系统的相册中
  2. Two    <AssetsLibrary/AssetsLibrary.h>苹果原生框架
  3. Three  iOS8推出的<Photos/Photos.h>
一共有两种方法自定义相册第一种是iOS9之后过期的 <AssetsLibrary/AssetsLibrary.h>苹果原生框架第二种是iOS8推出的<Photos/Photos.h> 苹果原生框架,功能更多,但是只支持iOS8之后的版本一般推荐使用<Photos/Photos.h> ,因为现在版本快iOS10了,有些版本没有升级的用户已经可以抛弃了
 1.添加图片到【相机胶卷】 1> UIImageWriteToSavedPhotosAlbum函数 2> AssetsLibrary框架 3> Photos框架(推荐) 2.拥有一个【自定义相册】 1> AssetsLibrary框架 2> Photos框架(推荐) 3.将刚才添加到【相机胶卷】的图片,引用(添加)到【自定义相册】 1> AssetsLibrary框架 2> Photos框架(推荐)

One:

如果只需要将要将图片保存到系统的相册中,只需要下面两句代码就搞定了

#文档里已经说明这个方法是保存到用户的相机胶卷里面的Adds the specified image to the user’s Camera Roll album.
- (void)saveBtns{//    /**//     *  保存到相册的方法//     *  @param image#>              需要保存的图片//     *  @param completionTarget#>   哪个控制器 description#>//     *  @param completionSelector#> 哪个方法 点击方法文档里面有提示 description#>//     *  @param contextInfo#>        参数,传什么现实什么 description#>//     *  @return//     */    UIImageWriteToSavedPhotosAlbum(self.imageView.image, self,  @selector(image:didFinishSavingWithError:contextInfo:), @"传什么下面就调用什么什么");}
// 需要实现下面的方法,或者传入三个参数即可
 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{    if (error) {        [SVProgressHUD showErrorWithStatus:@"保存失败"];    }else    {        [SVProgressHUD showSuccessWithStatus:@"保存成功"];    }}
#注意: @selector() 方法一定要传入三个参数,不然图片虽然保存进去了,但是会崩了因为参数越界实参个数 > 形参个数, 就会出现参数越界 -[NSInvocation setArgument:atIndex:]: index (2)out of bounds [-1,1] :

Two:

需要用到<AssetsLibrary/AssetsLibrary.h>这个库

官方文档给出的提示
//自定相册的类#import <AssetsLibrary/AssetsLibrary.h>static NSString *kGroupNameKey = @"nameKey";static NSString *kDefaultGroupName = @"会跳舞的狮子";
/** 懒加载 只创建一次library对象 */- (ALAssetsLibrary *)library{    if (!_library) {        _library = [[ALAssetsLibrary alloc] init];    }    return _library;}
- (NSString *)groupName{    //先从沙盒中取得名字    NSString *groupName = [[NSUserDefaults standardUserDefaults] stringForKey:kGroupNameKey];    if (groupName == nil) {//如果沙盒中取不到这个key(文件夹的名字)        groupName = kDefaultGroupName;        //储存名字到沙盒里面        [[NSUserDefaults standardUserDefaults] setObject:groupName forKey:kGroupNameKey];        //synchronize 立马将上面的key保存到沙盒里面        [[NSUserDefaults standardUserDefaults]synchronize];    }    return groupName;}
/**  点击保存按钮 */- (IBAction)clickSave:(id)sender { //创建自定义相册    //获得文件夹的名字 (调用从沙盒里面取的这个方法)    __block NSString *groupName = [self groupName];    //self的弱引用    __weakSelf;  //图片库    __weak ALAssetsLibrary *weakLibrary = self.library;    //创建自定义的相册    [weakLibrary addAssetsGroupAlbumWithName:groupName resultBlock:^(ALAssetsGroup *group) {        if (group) { //新创建的文件夹            //直接把图片添加到文件夹中            [weakSelf addImageToGroup:group];        }else{        //遍历相册中的每一个文件        [weakLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {            //取出文件夹的名称            NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];            if ([name isEqualToString:groupName]) { //如果相等,那么就是自己创建的文件夹                //添加图片到文件夹中                [weakSelf addImageToGroup:group];                *stop = YES; // 将图片添加到了文件夹中就停止遍历            }else if ([name isEqualToString:@"Camera Roll"])            {                //文件夹被用户强制删除了 (拼接一个空格,就是不同的文件夹的名字)                groupName = [groupName stringByAppendingString:@" "];                //储存新的名字                [[NSUserDefaults standardUserDefaults] setObject:groupName forKey:kGroupNameKey];                [[NSUserDefaults standardUserDefaults]synchronize];                //创建新的文件夹中                [weakLibrary addAssetsGroupAlbumWithName:groupName resultBlock:^(ALAssetsGroup *group) {                    //添加图片到文件夹中                    [weakSelf addImageToGroup:group];                } failureBlock:nil];            }        } failureBlock:nil];        }    } failureBlock:nil];}
/** 添加一张图片到某个文件夹中 */- (void)addImageToGroup:(ALAssetsGroup *)group{    __weak ALAssetsLibrary *weakLibrary = self.library;    //需要保存的图片    CGImageRef image = self.imageView.image.CGImage;    //添加图片到相机胶卷 (因为要先存到全部的相片里面. 在根据对应的assetURL)    [weakLibrary writeImageToSavedPhotosAlbum:image metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {        // asset就是一张照片        [weakLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) {            //将照片保存到自定的文件夹中            [group addAsset:asset];            [SVProgressHUD showSuccessWithStatus:@"保存成功"];        } failureBlock:nil];    }];}

Three:

用苹果iOS推出<Photos/Photos.h> 这个库先简单的介绍下,然后再上代码

Photos框架须知 1.PHAsset : 一个PHAsset对象代表一张图片或者一个视频文件 1> 负责查询一堆的PHAsset对象 2.PHAssetCollection : 一个PHAssetCollection对象代表一个相册 1> 负责查询一堆的PHAssetCollection对象 3.PHAssetChangeRequest 1> 负责执行对PHAsset的【增删改】操作 2> 这个类只能放在-[PHPhotoLibrary performChanges:completionHandler:] 或者 -[PHPhotoLibrary performChangesAndWait:error:]方法的block中使用 4.PHAssetCollectionChangeRequest 1> 负责执行对PHAssetCollection的【增删改】操作 2> 这个类只能放在-[PHPhotoLibrary performChanges:completionHandler:] 或者 -[PHPhotoLibrary performChangesAndWait:error:]方法的block中使用错误信息 This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:] 解决防范 // Asynchronously 异步执行操作 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{    [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } completionHandler:^(BOOL success, NSError * _Nullable error) {    JHLog(@"保存完毕") }]; // Synchronously 同步执行操作 NSError *error = nil; [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{    [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } error:&error]; // 这个方法只适合加载普通的plist文件,不能用来加载Info.plist [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Test" ofType:@"plist"]];安全提示按钮选择    // PHAuthorizationStatusNotDetermined    // 用户还没有对当前App授权过(用户从未点击过Don't Allow或者OK按钮)    // PHAuthorizationStatusRestricted    // 因为一些系统原因导致无法访问相册(比如家长控制)    // PHAuthorizationStatusDenied    // 用户已经明显拒绝过当前App访问相片数据(用户已经点击过Don't Allow按钮)    // PHAuthorizationStatusAuthorized    // 用户已经允许过当前App访问相片数据(用户已经点击过OK按钮)#  只有遵守了NSFastEnumeration协议的对象才能使用for-in循环

封装好的代码,可以根据公司的需求进行修改
我创建新的相册的名字就是APP的名字,

// 获取软件的名字作为相册的标题
NSString title = [NSBundle mainBundle].infoDictionary[(NSString )kCFBundleNameKey];


定义专属相册
#import <Photos/Photos.h>// 在interface中写方法的声明,是为了点语法有智能提示- (PHFetchResult<PHAsset *> *)createdAssets;- (PHAssetCollection *)createdCollection;
/** *  获得刚才添加到【相机胶卷】中的图片 */- (PHFetchResult<PHAsset *> *)createdAssets{    __block NSString *createdAssetId = nil;    // 添加图片到【相机胶卷】    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{        createdAssetId = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier;    } error:nil];    if (createdAssetId == nil) return nil;    // 在保存完毕后取出图片    return [PHAsset fetchAssetsWithLocalIdentifiers:@[createdAssetId] options:nil];}
/** *  获得【自定义相册】 */- (PHAssetCollection *)createdCollection{    // 获取软件的名字作为相册的标题    NSString *title = [NSBundle mainBundle].infoDictionary[(NSString *)kCFBundleNameKey];    // 获得所有的自定义相册    PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];    for (PHAssetCollection *collection in collections) {        if ([collection.localizedTitle isEqualToString:title]) {            return collection;        }    }    // 代码执行到这里,说明还没有自定义相册    __block NSString *createdCollectionId = nil;    // 创建一个新的相册    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{        createdCollectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier;    } error:nil];    if (createdCollectionId == nil) return nil;    // 创建完毕后再取出相册    return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionId] options:nil].firstObject;}
/** *  保存图片到相册 */- (void)saveImageIntoAlbum{    // 获得相片    PHFetchResult<PHAsset *> *createdAssets = self.createdAssets;    // 获得相册    PHAssetCollection *createdCollection = self.createdCollection;    if (createdAssets == nil || createdCollection == nil) {        [SVProgressHUD showErrorWithStatus:@"保存失败!"];        return;    }    // 将相片添加到相册    NSError *error = nil;    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{        PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection];        [request insertAssets:createdAssets atIndexes:[NSIndexSet indexSetWithIndex:0]];    } error:&error];    // 保存结果    if (error) {        [SVProgressHUD showErrorWithStatus:@"保存失败!"];    } else {        [SVProgressHUD showSuccessWithStatus:@"保存成功!"];    }}
- (IBAction)save {    /*     requestAuthorization方法的功能     1.如果用户还没有做过选择,这个方法就会弹框让用户做出选择     1> 用户做出选择以后才会回调block     2.如果用户之前已经做过选择,这个方法就不会再弹框,直接回调block,传递现在的授权状态给block     */    PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus];    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {        dispatch_async(dispatch_get_main_queue(), ^{            switch (status) {                case PHAuthorizationStatusAuthorized: {                    //  保存图片到相册                    [self saveImageIntoAlbum];                    break;                }                case PHAuthorizationStatusDenied: {                    if (oldStatus == PHAuthorizationStatusNotDetermined) return;                    JHLog(@"提醒用户打开相册的访问开关")                    break;                }                case PHAuthorizationStatusRestricted: {                    [SVProgressHUD showErrorWithStatus:@"因系统原因,无法访问相册!"];                    break;                }                default:                    break;            }        });    }];

iOS相册中如何删除照片

最近公司的app有一个新功能是在app中删除相册的照片 ,本来是一个比较简单地功能,在做的过程中却发现AssetsLibary 框架并没有提供删除相册的API,网络上查找的时候这方面的信息也很少,最终在stackoverflow上发现了一个巧妙的方法,使用[ALAsset setImageData:metadata:completionBlock:]来实现删除照片的功能,可是也有人说这个API虽然能删除照片,但是它的主要功能不是用来删除照片,在iOS8的时候再只用它删除照片就无效了。好在iOS8中我们可以直接使用 PhotoKit框架来完成操作,PhotoKit中直接提供了 [PHAssetChangeRequest deleteAssets:@[Asset]]API来完成对照片的删除功能。接下来我们介绍一下这两个照片库框架如何删除照片。

在以前的iOS App中中我们通常用AssetsLibary框架来完成对照片库的操作,但是随着iOS 系统的更新,苹果在相机和照片库上都发生了很大的改变,比如最新的iOS9系统中会有单独的自拍、屏幕快照相册,现在仅仅使用AssetsLibary并不能对照片库进行很好地支持。在iOS8中Apple提供了新的框架 PhotoKit,相比老旧的AssetsLibary,PhotoKit表现的更好,更能完成设备和照片库的无缝工作。但是在现在的苹果用户中,iOS7系统还是占有很大的比例,所以AssetsLibary仍然具有使用意义。

AssetsLibary删除照片(用于iOS7)

1.在相册中添加一张照片
ALAssetsLibrary *lib = [[ALAssetsLibrary alloc]init];    UIImage *image = [UIImage imageNamed:@"pet"];    [lib writeImageToSavedPhotosAlbum:image.CGImage metadata:@{} completionBlock:^(NSURL *assetURL, NSError *error) {        NSLog(@"Write image(%@) to album . Error:(%@)", assetURL, error);    }];

2.在相册中删除照片
ALAssetsLibrary *lib = [[ALAssetsLibrary alloc]init];    [lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {            if (result.isEditable) {              //在这里imageData 和 metaData设为nil,就可以将相册中的照片删除                [result setImageData:nil metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {                    NSLog(@"asset url(%@) should be delete . Error:%@ ", assetURL, error);                }];            }        }];    } failureBlock:^(NSError *error) {    }];

PhotoKit 删除照片(用于iOS8, iOS9)

1.在相册中添加一张照片

//首先获取相册的集合    PHFetchResult *collectonResuts = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:[PHFetchOptions new]] ;    //对获取到集合进行遍历        [collectonResuts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        PHAssetCollection *assetCollection = obj;    //Camera Roll是我们写入照片的相册    if ([assetCollection.localizedTitle isEqualToString:@"Camera Roll"])  {            [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{      //请求创建一个Asset                    PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[UIImage imageNamed:@"pet"]];      //请求编辑相册                     PHAssetCollectionChangeRequest *collectonRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];      //为Asset创建一个占位符,放到相册编辑请求中       PHObjectPlaceholder *placeHolder = [assetRequest placeholderForCreatedAsset ];      //相册中添加照片                [collectonRequest addAssets:@[placeHolder]];            } completionHandler:^(BOOL success, NSError *error) {                NSLog(@"Error:%@", error);            }];       }      }];
2.在相册中删除照片
PHFetchResult *collectonResuts = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAny options:[PHFetchOptions new]] ;    [collectonResuts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        PHAssetCollection *assetCollection = obj;        if ([assetCollection.localizedTitle isEqualToString:@"Camera Roll"])  {            PHFetchResult *assetResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:[PHFetchOptions new]];            [assetResult enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {               [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{                   //获取相册的最后一张照片                   if (idx == [assetResult count] - 1) {                       [PHAssetChangeRequest deleteAssets:@[obj]];                   }               } completionHandler:^(BOOL success, NSError *error) {                   NSLog(@"Error: %@", error);               }];            }];        }    }];

参考原文:http://www.jianshu.com/p/ac18aa3f28c2

https://123sunxiaolin.github.io/2016/08/27/iOS中,系统相册的那些事/

 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 认床导致睡不着怎么办 碰到打呼噜的人怎么办 打呼吵得睡不着怎么办 打呼太吵睡不着怎么办 睡觉时舍友说话怎么办 夜晚醒了睡不着怎么办 夜晚怕黑睡不着怎么办 宝宝不愿意盖被子怎么办 白天睡觉晚上睡不着怎么办 晚上睡觉不安神怎么办 晚上经常睡不着觉怎么办 老是睡不着觉怎么办啊 小孩睡觉不安稳怎么办 睡觉时动不了怎么办 特别累还睡不着怎么办 又累又睡不着怎么办 干活累的睡不着怎么办 狗一有动静就叫怎么办 楼上天天闹动静怎么办 喝了奶茶失眠怎么办 失眠一宿第二天怎么办 睡觉外面噪音大怎么办 怀孕早期晚上睡不着怎么办 短发发尾翘怎么办 很累就是睡不着怎么办 人累但是睡不着怎么办 如果晚上睡不着该怎么办 晚上睡不着觉该怎么办 晚上睡不着该怎么办呢 晚上失眠睡不着该怎么办 晚上一直睡不着该怎么办 怀孕晚上睡不着该怎么办 运动太累睡不着怎么办 运动完睡不着觉怎么办 晚上冷得睡不着怎么办 晚上脚冷睡不着怎么办 短发头发有点乱怎么办 不想让别人睡觉怎么办 15岁晚上睡不着怎么办 16岁青少年失眠怎么办 好累又睡不着怎么办