iOS开发------简单实现图片多选功能(Photos.fra

作者: RITL | 来源:发表于2016-08-11 16:46 被阅读2447次

Photos.framework是iOS8后苹果推出的一套替代AssetsLibrary.framework获取相册资源的原生库,至于AL库,欢迎大家给博文iOS开发------简单实现图片多选功能(AssetsLibrary.framework篇)提出宝贵的意见。

楼主大部分都是查看官方开发文档进行探索的(当然,实在不明白了也会请求google 的 0.0 )。这里就说一下个人的看法吧,相比AL库,Photos的开发文档显然更像是目前我们接触的ObjC语言(如果不信,可以对比一下AL库和Photos库的开发文档)。初次接触这个库的时候可能会感觉比较乱,毕竟类的数量比AL库多了好多,但在熟悉大体逻辑之后,就会发现它的分工比AL更加明确,并且使用起来要比AL灵活的多。

提醒一下,要使用相册资源库的时候,为了适配一下将来的iOS10,不要忘记在info.plist文件中加入NSPhotoLibraryUsageDescription这个描述字段啊,更多的权限坑请关注一下博文 iOS开发------iOS 10 由于权限问题导致崩溃的那些坑

2018-05-18 更新

针对OC版本进行了重构以及功能的扩充 OC传送门

RITLPhotosViewController *photoController = RITLPhotosViewController.photosViewController;
photoController.configuration.maxCount = 5;//最大的选择数目
photoController.configuration.containVideo = false;//选择类型,目前只选择图片不选择视频
photoController.photo_delegate = self;
photoController.thumbnailSize = self.assetSize;//缩略图的尺寸

[self presentViewController:photoController animated:true completion:^{}];

2017-01-22 更新

Swift - 全代码:https://github.com/RITL/Swift-RITLImagePickerDemo

Swift-Demo 重写完不久,可能Swift的编程思想还不是领略的很好,但楼主会继续努力。



Swift用法:

//获得控制器
let viewController : RITLPhotoNavigationViewController = RITLPhotoNavigationViewController()

//设置viewModel属性
let viewModel = viewController.viewModel

// 获得图片
viewModel.completeUsingImage = {(images) in

    
}

// 获得资源的data数据
viewModel.completeUsingData = {(datas) in
    
    //coding for data ex: uploading..
    print("data = \(datas)")
}

self.present(viewController, animated: true) {}

话说的有点多了,下面就谈谈个人对Photos的理解,这里只记录一下Photos.framework中类的使用与理解,真正的实现多选功能请前去上面的链接下载demo查看,多谢指正:

类逻辑

研究一个库或者框架,总体逻辑一定是要缕清的,下面就是个人对photos的理解,有点多,分类一下吧:

资源类

  • PHPhotoLibrary 是一个资源库。能够获取相册权限以及对相册的操作,与AL不同,它不能获取资源对象哦.
  • PHFetchResult 是一个结果集,一个泛型类。通过方法获取到的相册或者资源组就是被封装成该类返回.
  • PHAssetCollection 是一个资源集合对象。其实它就是一个相册的概念,可通过类方法获得想要的相册集合,继承自PHCollection.
  • PHCollectionList 是一个资源集合列表对象。刚接触时以为它是存放PHCollection对象的集合,后来才知道,如果想要通过地点以及时间分组的话,请使用这个类替代PHAssetCollection吧,用法与PHAssetCollection类似,同样是继承自PHCollection.
  • PHAsset 是一个独立的资源对象。可以通过类方法对PHCollection对象进行遍历,获得存放Asset对象的结果集,可以直接获得资源的规格数据,若想获得图片以及原图等资源,需要配合PHImageManager对象,继承自PHObject.

工具类

  • PHFetchOptions 一个遍历配置类。一般情况下,当存在遍历方法的时候就存在这个类型的参数,里面含有谓词、遍历顺序等属性,可以通过设置这些属性,完成不同的遍历.
  • PHImageManager 是一个负责渲染资源的类。比如获得PHAsset对象的原图等操作需要使用该类.
  • PHCachingImageManager 继承自PHImageManager,可以对请求的资源对象进行缓存,这样再次获取时就不需要重新渲染,在加快获取速度的同时也降低了CPU的压力,这里最好对缓存的PHImageRequestID进行一下记录,防止同一资源被无限缓存的尴尬.
  • PHImageRequestOptions 是一个资源请求的配置类。通常在使用PHImageManager对某个资源进行请求时都会存在此类型的参数,可以在请求资源时对该对象进行设置,获得想要的结果,比如原图..

请求类

  • 请求类不能独立使用,要想发挥作用,需要与PHPhotoLibrary对象配合使用.
  • PHAssetCollectionChangeRequest 集合变化请求类,负责对PHAssetCollection对象的操作
  • PHCollectionListChangeRequest 集合变化请求类,负责PHCollectionList对象的操作
  • PHAssetChangeRequest 资源变化请求类,负责PHAsset对象的操作

类库中的类及其属性方法:

这里提到的都是代码中用到的属性和方法,如果只是为了多图选择,那么以下的方法应该是够用的,不够的话可以Command+单击进入开发文档查看即可。

PHPhotoLibrary_照片库

基础方法

我觉得下面的方法应该都懂,毕竟每个涉及到权限的库都会存在下面三个方法的.

//获得单例对象
+ (PHPhotoLibrary *)sharedPhotoLibrary;
//获得相册权限
+ (PHAuthorizationStatus)authorizationStatus;
//请求权限
+ (void)requestAuthorization:(void(^)(PHAuthorizationStatus status))handler;

操作相册

之前说请求类不能独自使用,需要配合PHPhotoLibrary对象,为什么这么说呢,是因为在使用请求类的时候必须使用下面两个方法其中之一,下面是开发文档的一句话:

/*表示请求只能通过下面两种方法的block进行创建和使用,所有的ChangeRequest类上面都会存在这句话,当然类名肯定不一样的.*/
PHAssetCollectionChangeRequest can only be created or used within a -[PHPhotoLibrary performChanges:] 
or -[PHPhotoLibrary performChangesAndWait:] block.

//异步执行change的变化请求
- (void)performChanges:(dispatch_block_t)changeBlock completionHandler:(nullable void(^)(BOOL success, NSError *__nullable error))completionHandler;

//同步执行change的请求变化
- (BOOL)performChangesAndWait:(dispatch_block_t)changeBlock error:(NSError *__autoreleasing *)error;

其实我感觉只看上面的两个方法感觉会比较抽象,那么就拿出Demo中的两段小源码举个例子,相信这样就比较好理解了.

新建相册

///新建一个名字叫做title的相册
-(void)addCustomGroupWithTitle:(NSString *)title
             completionHandler:(void (^)(void))successBlock
                      failture:(void (^)(NSString * _Nonnull))failtureBlock
{
    [self.photoLibaray performChanges:^{
        
        //创建一个创建相册的请求
        [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
        
    }completionHandler:^(BOOL success, NSError * _Nullable error) {
        
        if (success == true)//成功
        {
            successBlock();return ;
        }
        //失败
        failtureBlock(error.localizedDescription);
    }];
}

向相册里面添加图片

///向collection中添加图片
-(void)addCustomAsset:(UIImage *)image
           collection:(PHAssetCollection *)collection
    completionHandler:(void (^)(void))successBlock
             failture:(void (^)(NSString * _Nonnull))failtureBlock
{
    //执行变化请求
    [self.photoLibaray performChanges:^{
        
        //如果相册允许操作
        if([collection canPerformEditOperation:PHCollectionEditOperationAddContent])
        {
            //创建资源请求对象
            PHAssetChangeRequest * assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
            
            //创建相册请求对象
            PHAssetCollectionChangeRequest * groupChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
            
            //向相册中添加资源
            [groupChangeRequest addAssets:@[assetChangeRequest.placeholderForCreatedAsset]];
        
        }
        
    }completionHandler:^(BOOL success, NSError * _Nullable error) {
        
        if (success == true)//成功
        {
            successBlock();return;
        }
        //失败
        failtureBlock(error.localizedDescription);
    }];
}

//这里不止能够通过图片对象创建,还存在如下两种创建方法
+ (nullable instancetype)creationRequestForAssetFromImageAtFileURL:(NSURL *)fileURL;//通过图片所在的路径url进行创建

+ (nullable instancetype)creationRequestForAssetFromVideoAtFileURL:(NSURL *)fileURL;//通过视频所在的路径url进行创建

PHAssetCollection_资源集合对象

  • 常用属性
//组的标题,比如Camera Roll(胶卷相册)
@property (nonatomic, strong, readonly, nullable) NSString *localizedTitle;

//资源组的类型,比如是智能相册,普通相册还是外界创建的相册
PHAssetCollectionType assetCollectionType;

typedef NS_ENUM(NSInteger, PHAssetCollectionType) {
    PHAssetCollectionTypeAlbum      = 1, //传统相册
    PHAssetCollectionTypeSmartAlbum = 2, //智能相册
    PHAssetCollectionTypeMoment     = 3, //自定义创建的相册
} NS_ENUM_AVAILABLE_IOS(8_0);

//具体的子类型,比如是智能相册的自拍还是喜爱等,这个枚举类太多,就不进行粘贴了.
PHAssetCollectionSubtype assetCollectionSubtype;

//资源组中资源的大约数量,不一定准,如果想要确切的,获得PHFetchResult对象取count即可
NSUInteger estimatedAssetCount;

//最早的一张图片存在相册的时间
NSDate *startDate;

//最近的一张图片存在相册的时间
NSDate *endDate;
  • 获得具体资源的方法,基本都是通过类方法进行获取,这样就降低了PhotosLibrary对象复杂度。
//判断是否能够进行编辑,如果是进行修改请求,最好通过这个方法来判断是下
- (BOOL)canPerformEditOperation:(PHCollectionEditOperation)anOperation;

//获得智能分组,比如胶卷相册,最近添加,自拍等
PHFetchResult * smartGroups = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
                                                                       subtype:PHAssetCollectionSubtypeAlbumRegular
                                                                       options:nil];

//获得我们自定义创建的相册组,比如有QQ的手机应该都会有QQ这个相册,那么通过该方法就可以获取的到
+ (PHFetchResult<PHCollection *> *)fetchTopLevelUserCollectionsWithOptions:(nullable PHFetchOptions *)options;

如果PHFetchResult觉得用起来不是很爽的话,可以将其包装成数组来进行下一步的操作,Demo中就是将其打包成数组来进行操作的:

@implementation PHFetchResult (NSArray)

//将PHFetchResult对象转成NSArray对象
-(void)transToArrayComplete:(void (^)(NSArray<PHAssetCollection *> * _Nonnull, PHFetchResult * _Nonnull))arrayObject
{
    __weak typeof(self) weakSelf = self;
    
    NSMutableArray *  array = [NSMutableArray arrayWithCapacity:0];
    
    if (self.count == 0)
    {
        arrayObject([array mutableCopy],weakSelf);
        array = nil;
        return;
    }
    
    [self enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        [array addObject:obj];
        
        //如果遍历完毕,进行回调
        if (idx == self.count - 1)
        {
            arrayObject([array mutableCopy],weakSelf);
        }
    }];
}

@end

PHAsset_资源对象

  • 常用属性
//资源媒体的类型
PHAssetMediaType mediaType;

typedef NS_ENUM(NSInteger, PHAssetMediaType) {
    PHAssetMediaTypeUnknown = 0,  //未知类型
    PHAssetMediaTypeImage   = 1,  //图片类型
    PHAssetMediaTypeVideo   = 2,  //视频类型
    PHAssetMediaTypeAudio   = 3,  //音频类型
} NS_ENUM_AVAILABLE_IOS(8_0);

//资源美图的子类型,比如如果资源是图片,那么它是全景还是HDR,如果是iOS9,还能知道他是屏幕截图还是live图片,枚举有点多,也不再次粘贴了.
PHAssetMediaSubtype mediaSubtypes;

//资源的像素宽
NSUInteger pixelWidth;

//资源的像素高
NSUInteger pixelHeight;

//资源的创建日期
NSDate *creationDate;

//资源的最近一次修改的时间
NSDate *modificationDate;

//资源拍摄的地点
CLLocation *location;

//如果是音频或者视频,它的持续时间
NSTimeInterval duration;

//它是否被隐藏
BOOL hidden;

//它是否是喜爱的
BOOL favorite;
  • 常用搭配使用方法
//请求图片,将想要获取Image实体的资源,裁剪的大小以及方式进行获取图片
//如果想要原图,设置PHImageRequestOptions对象的deliveryMode属性为PHImageRequestOptionsDeliveryModeHighQualityFormat即可
[[PHImageManager defaultManager]requestImageForAsset:asset
                                          targetSize:size
                                         contentMode:PHImageContentModeAspectFill
                                             options:option
                                       resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
    
    //通过block回传图片,并将部分信息存在于info字典中,并且该方法的返回值可以在info字典中找到
}];
//请求数据,获取资源的Data对象,可以用来计算资源的大小。
//这样可以避免UIImage->Data导致内存以及CPU瞬间激增
[[PHImageManager defaultManager]requestImageDataForAsset:asset
                                                 options:option
                                           resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
    //在block里面获取图片的各种信息
}];
//这里最好存在一个标位置或者其他方法标志一下,避免每次都要缓存导致的卡顿以及CPU卡死
[((PHCachingImageManager *)[PHCachingImageManager defaultManager])startCachingImagesForAssets:@[copy_self]
                                                                                   targetSize:newSize
                                                                                  contentMode:PHImageContentModeAspectFill
                                                                                      options:nil];

PHFetchResult_结果集合

表示乍一看,是不是和数组很相似呀.

  • 属性
//当前集合的数量
NSUInteger count;

//获得index位置的对象
- (ObjectType)objectAtIndex:(NSUInteger)index;

//是否包含对象
- (BOOL)containsObject:(ObjectType)anObject;

//对象的索引
- (NSUInteger)indexOfObject:(ObjectType)anObject;

//第一个对象
ObjectType firstObject;

//最后一个对象
ObjectType lastObject;
  • 遍历方法,应该也是获取集合内部数据的唯一方法了.
/*使用Block进行枚举遍历,stop控制是否停止,每次获得数据都会执行一次回调*/
- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;

/*根据枚举类型进行枚举,比如正序还是倒序*/
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;

/*枚举特定区间并按照响应枚举类型进行遍历*/
- (void)enumerateObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts usingBlock:(void (^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;

相册发生变化

使用PHPhotoLibrary对象注册观察者,当然,不要在dealloc或者特定的地方注销观察者啊,与KVO相同.

//注册观察者
- (void)registerChangeObserver:(id<PHPhotoLibraryChangeObserver>)observer;

//注销观察者
- (void)unregisterChangeObserver:(id<PHPhotoLibraryChangeObserver>)observer;

PHPhotoLibraryChangeObserver协议方法

//This callback is invoked on an arbitrary serial queue.
//If you need this to be handled on a specific queue,
//you should redispatch appropriately.

//这个回调是在一个随意的线程中被唤起,如果需要在一个特定的线程中处理,应该在合适的地方重新唤起
//(翻译可能不太准确,如果需要更新,一般情况需要在主线程,这个应该都懂得.)
- (void)photoLibraryDidChange:(PHChange *)changeInstance;

实例

具体用法如下:

首先需要查看是否发生了变化,如果没有变化,那么就返回nil;如果发生了变化,就会返回响应类型的对象:

//PHChange对象的两个方法:

//获取PHObject对象的变化详情,其实PHAsset和PHCollection都是继承自PHObject的
- (nullable PHObjectChangeDetails *)changeDetailsForObject:(PHObject *)object;
-
//获取结果集的变化详情,和上面一样,如果不存在变化,返回nil
- (nullable PHFetchResultChangeDetails *)changeDetailsForFetchResult:(PHFetchResult *)object;

下面记录一下描述详细变化的类吧:

PHObjectChangeDetails

//PHObject对象变化详情对象
PHObjectChangeDetails.h

//变化之前的对象
@property (atomic, strong, readonly) __kindof PHObject *objectBeforeChanges;

//变化之后的对象,
@property (atomic, strong, readonly, nullable) __kindof PHObject *objectAfterChanges;

//内容是否发生了变化
@property (atomic, readonly) BOOL assetContentChanged;

//该对象是否已经删除
@property (atomic, readonly) BOOL objectWasDeleted;

@end

/*
1、判断一下是否被删除了,如果被删除了,那么请把数据源的该对象也删除了吧,并重新reload一下当前的视图.
2、如果没有被删除,就可以知道是否发生了变化,那么,获取变化后的内容对象并将之前的内容replace一下,刷新视图即可
*/

PHFetchResultChangeDetails

//PHFetchResult对象发生变化的详情类
PHFetchResultChangeDetails.h

//变化之前的结果集
@property (atomic, strong, readonly) PHFetchResult *fetchResultBeforeChanges;

//变化之后的结果集
@property (atomic, strong, readonly) PHFetchResult *fetchResultAfterChanges;

/*
这个变量很有意思:
如果为true,表示集合发生了增删改,那么通过一下面的删除、新增以及更新操作的响应属性或方法进行数据的修改即可。
如果为false,则表示发生了大的改变,不在提供下面那些变化的详情,只能使用fetchResultAfterChanges属性对该属性进行替换即可*/
@property (atomic, assign, readonly) BOOL hasIncrementalChanges;

//如果是删除操作,返回删除的位置以及删除的对象
@property (atomic, strong, readonly, nullable) NSIndexSet *removedIndexes;
@property (atomic, strong, readonly) NSArray<__kindof PHObject *> *removedObjects;

//如果是新增操作,返回新增的位置以及新增的对象
@property (atomic, strong, readonly, nullable) NSIndexSet *insertedIndexes;
@property (atomic, strong, readonly) NSArray<__kindof PHObject *> *insertedObjects;

//如果是更新操作,返回更新的位置以及更新的对象
@property (atomic, strong, readonly, nullable) NSIndexSet *changedIndexes;
@property (atomic, strong, readonly) NSArray<__kindof PHObject *> *changedObjects;

/*
1、判断一下hasIncrementalChanges值,如果为false,直接取fetchResultAfterChanges属性进行值的替换
2、如果为true,根据下面的详情数据进行相应操作即可,当然,使用全体替换的方法也是可以的,但是单个操作可以使用动画哦
*/

吐槽

我要开始吐槽啦!其实毕业回学校的时候无聊,想练习一下Swift,研究过这个库,大体的功能与博文Demo的功能差不多,但由于起名太随便,随手删了,没错..删了!(还真是感谢我随手清理垃圾篓的习惯,呵呵....所以大家一定要不忘记备份呀,= = 再就是起名不要太随便啊),这个Demo是趁工作的业余时间写的,目的是加深对Photos库理解的同时不辜负学校的那段时间,<font color=red>不太建议直接拿本文的Demo直接放入工程中使用哦,Demo的目的只是为了学习一下Photos库,尽管对Demo进行了一些内存泄露的处理,但每次还是会有大约1MB多的内存多余占用,这个问题会在之后楼主不断进步的过程中进行修复的</font>

记录完毕3Q

相关文章

网友评论

  • 换个帅气的昵称啦:你好
    - (void)photosViewController:(UIViewController *)viewController
    assetIdentifiers:(NSArray <NSString *> *)identifiers
    这个identifiers里的值是图片本地路径吗
    如果不是 我想获取图片本地路径那该怎么做
    换个帅气的昵称啦:@RITL 你好 -(void)photosViewController:(UIViewController *)viewController datas:(NSArray<NSData *> *)datas 返回的datas 是空的
    RITL:@换个帅气的昵称啦 有一个data代理方法,里面看看
  • 换个帅气的昵称啦:你好 我想获取controller dismiss 的方法 该如何操作
    换个帅气的昵称啦:@RITL 因为不可能选完就在里面往服务器传图片的吧 应该那个页面消失后才传图片的 是不是这样子的呢
    RITL:@换个帅气的昵称啦 这个是有什么作用吗?:smiley:
  • bb4cf902bdbc:大神你好,我想问一下 我下载了 OC版本的demo,把代码拷贝到我自己的项目中,跳转到相册后,发现一张图片都没有,请问这是什么原因,有点崩溃 实在查不出来了,
    RITL:是不是没有权限,现阶段版本只是确保了一下没有权限不会崩溃,下一个版本我加一下对没有权限进行一下提示,你看看权限是不是没开。
  • 月子我的嫁:请教一下想删除图片怎么处理
    调用了- (void)photosCellDidTouchUpInSlide:(RITLPhotosCell *)cell
    asset:(PHAsset *)asset
    indexPath:(NSIndexPath *)indexPath
    complete:(RITLPhotosCellStatusAction)animated;
    这个方法 返回值全是空
    RITL:@月子我的嫁 有一个代理方法可以获得选中的资源id,如果在外部删除了选中的,那么可以在记录ids的数组中删除,然后赋值给`photoController.defaultIdentifers`即可,在进入图片选择的时候就不会显示选中了:smile: 希望我理解对了
    月子我的嫁:@RITL 就是在外部的展示控制器中移除选中的图片 例如三张中的第二张 请问需要怎么处理呢
    RITL:您好,我没明白您是什么意思,就是说从外面删除了照片吗还是什么?
  • 1c005a4b7f1e:你这个第三方写的有问题,选择了图片5个代理方法有2个返回图片的代理不走方法
    RITL:@出云居士 您好,能告诉我一下三方的版本是多少吗?
    1c005a4b7f1e:@RITL 我用的就是最新的代理方法,photosViewController:thumbnailImages:infos:和photosViewController:images:infos:这2个方法不走,我的手机是10.3.3版本的,怎么调试都没用
    RITL:您好,刚才试了一下,方法是走的,为了适配之前的版本,有两个方法废弃掉了,如果使用了最新的代理方法,那么老的那个代理方法是不走的,下面是我的调用顺序:
    ```
    2018-09-03 15:16:35.613472+0800 RITLPhotoDemo[4810:320181] INFO: Reveal Server started (Protocol Version 46).
    2018-09-03 15:16:47.520056+0800 RITLPhotoDemo[4810:320181] photosViewController:assetIdentifiers:
    2018-09-03 15:16:47.520329+0800 RITLPhotoDemo[4810:320181] photosViewController:assets:
    2018-09-03 15:16:47.524490+0800 RITLPhotoDemo[4810:320181] photosViewController:thumbnailImages:infos:
    2018-09-03 15:16:47.624587+0800 RITLPhotoDemo[4810:320181] photosViewController:images:infos:
    2018-09-03 15:16:47.626661+0800 RITLPhotoDemo[4810:320181] photosViewController:datas:
    ```
  • 39198d66ee03:我觉得,那个相册分组,无图片(资源)的,不要给他分组,有图片(资源)的才给分组,会不会好点。
    39198d66ee03:@RITL 嗯嗯,可以用个属性控制,像限制最大选择图片个数一样,用BOOL类型(或者其他),可能有些人需要,有些人不需要,都可以兼容。
    RITL:@逆风落亿 嗯,很好的建议,下一个版本我改一下:smile::smile:
  • 39198d66ee03:用了你的最新版本,你的默认限制是5张照片,我在相机胶卷缩略图页面,是不能超过5张,在点击缩略图再选择的时候能够选择超过5张的照片,可能是缺少逻辑判断。还是设计交互模式是这样的。
    RITL:您好,很不好意思,这是一个bug,最新的2.2.1版本刚刚修复了一下,Pod更新一下试试,谢谢反馈的bug哈
  • 60e694baaec2:今天使用的时候碰见了两个问题,1.我想要调用系统图片时返回的info里的数据,但是我看代理好像没有返回info里的数据(也可能是我用的时间比较短没有发现),希望大佬有时间的时候辛苦一下加上,2.添加AppleReachability依赖库的时候和我原项目中的Reachability库冲突,原因是两个库里都有kReachabilityChangedNotification这个属性,修改其中一个库这个属性名(kReachabilityChangedNotification)就好了
    RITL:您好,2.2.0版本针对代理方法进行了扩充并作了Deprecated标注,使用新的代理方法就能得到info信息了,当然原来的代理方法也不会报错,pod更新一下就好了;AppleReachability这个确实是我疏忽了,当时直接拿了Apple的代码改了个名字,当然现在也改过来了😀
  • 204bd5e29d96:相册图片在iCloud储存的,无法预览,选中后返回回调没有图片。能否把iCloud图库过滤掉?
    RITL:您好,这个问题在2.1.6版本应该已经修复了,刚发布完版本,你可以试一下:blush:
    RITL:@羊喜喜雨 好的,我看一下去,谢谢:smile:
  • 小白奔哥:第一次上传图片没问题,第二次打开相册就奔溃了,打开僵尸调试模式,出现[PHAsset retain]: message sent to deallocated instance 0x116779010,现在知道是PHAsset出问题了,但不知道应该在哪里把它delloc掉
    RITL:@奔哥_14c0 如果下次还出现这种问题,能把崩溃的断点发到github上的Issues上么,我看一下并尝试修复下:smile:
    小白奔哥:@RITL 因机型而异,普遍情况下是内存较小手机的存在。我这边的操作是调起相册,选择上传给后台,返回当前页面,如此重复操作。奔溃在选择照片/有时候奔溃在返回上一个页面的返回按钮这里。
    RITL:能详细说一下复现步骤吗,我试一下
  • 换个帅气的昵称啦:是否打开相册 点不允许的时候程序奔溃
    换个帅气的昵称啦:@RITL 你好 第一次打开app范文相册的时候为什么 会跳到相册再询问是否打开相册,不是应该先询问是否打开相册,然后才调到相册吗
    RITL::smiley: 不好意思呀,最近很忙,最新版的已经完全修复了这个问题,谢谢你发现的问题哈
    RITL:@换个帅气的昵称啦 好的,谢谢,我晚上回到家马上看一下
  • 换个帅气的昵称啦:如果我想外面调用选择图片放大功能怎么调用你里面的方法
    RITL:@换个帅气的昵称啦 这个功能当时没有想到,很抱歉啊,后期我得扩充上,谢谢啦,你可以尝试一下KSPhotoBrowser(https://github.com/skx926/KSPhotoBrowser)这个:smile:
  • 95c797dbbaa6:确实深奥,demo完全看不懂,看来水平还是不够啊,不够演示效果不错
    95c797dbbaa6:@RITL 也或许是我水平不够,看不是很懂,不过也很好,望能做的通俗一点
    RITL:@Sunset673 现在看来那个库思路架构确实不对,很抱歉引起误导,后面有时间我回考虑重构的,谢谢:smile: :smile:
  • 徐小宾:鼓励作者使用系统原生库~
    RITL:@逆风落亿 好的,过段时间不那么忙了,我再优化一下,谢谢呀:smile:
    39198d66ee03:感觉内存没有优化好,我用了下,不太好用,有30多兆内存未释放,而且过滤系统相册太生硬,可以用统一的type过滤,为什么要用title过滤,如果项目需要支持多国语言,感觉会出问题。
  • dslCoding:完全看不懂你的demo写的是个啥,可能我水平太次
    dslCoding:@RITL 还是我了解太少,没有看出是MVVM架构,多学习
    RITL:额,就是练习Photos.framework写的一个图片多选,用的是MVVM,可能我的MVVM思想还不是很好,应该是楼主水平不够:smile:

本文标题:iOS开发------简单实现图片多选功能(Photos.fra

本文链接:https://www.haomeiwen.com/subject/jxrssttx.html