ios+html5+选取照片,iOS 自定义图片选择器 1 - PhotoKit
【 写在前面:笔者按照Instagram的图片选取器写了个小Demo,
该系列文章为笔者实现Demo的步骤,若有不正确的地方还望指出来,共同学习。
地址在最后】
iOS开发者对于图片选择器不会感到陌生,例如最常用的UIImagePicker就是系统提供的,可以实现简单的图片选取与编辑,当需要高度定制化的时候,就需要我们自己造轮子了。笔者就以Instagram为参考参考来造自己轮子。
当然,也能找到很多优秀的第三方,如:
MWPhotoBrowser:(https://github.com/mwaterfall/MWPhotoBrowser)
它是一个图片选取的框架,需要传入图片资源。我们的业务很多时候是直接取的系统的相册,而笔者造的轮子定位就是一个基于系统相册的自定义图片选择器。所以我们必须先了解下如何获取系统的图片资源。
在iOS 8以前想要与系统相册进行互动使用的是ALAsset,而在iOS9开始,苹果就不再推荐了。从iOS 8开始,苹果推出PhotoKit来取代ALAsset,PhotoKit还能够配合ICloud,且当下基本以iOS 8为最低版本,我们也就直接使用PhotoKit来进行开发。
使用选取器的基本的流程是(调用选取器->获取图片->展示图片->选取图片->回调并关闭),在实际流程中会有细节上的差异。
下面笔者会根据功能的先后,把主要使用到的方法依次列举出来。
1.权限的配置与获取
在iOS 10中需要添加额外的安全设定,否则程序会直接崩溃,我们用到了相册,所以需要在info.plist里添加NSPhotoLibraryUsageDescription的key值,其value为获取权限的描述,该描述会在设置中的相册权限展示。
要获取图片还要知道获取图片的权限是否开启,可调用以下方法:
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
/*当status等于PHAuthorizationStatusAuthorized表示用户已经授予了权限。
该方法在应用初次询问时,会直接弹出系统的权限询问,
用户操作后才会回调,所以不存在PHAuthorizationStatusNotDetermined
(用户还未对权限进行选择)的状态。*/
}];
//当然,也可以使用下方的方法直接获取权限的状态
//PHAuthorizationStatus state = [PHPhotoLibrary authorizationStatus];
2.获取相册信息
在用到PhotoKit的地方需要包含其头文件
#import
获取手机内所有的相册:
//search collection data
PHFetchResult * sysfetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
subtype:PHAssetCollectionSubtypeAlbumRegular
options:nil];
遍历相册,获取需要的值,如相册的Title:
for (PHAssetCollection * assetCollection in sysfetchResult) {
NSString * collectionTitle = assetCollection.localizedTitle;
}
获取相册所有图片的信息
/**get PHAsset from collection*/
- (NSArray *)getAssetWithCollection:(PHAssetCollection *)collection {
//set fetchoptions
PHFetchOptions * options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate"
ascending:YES]];
//search
NSMutableArray * assetArray = [NSMutableArray array];
PHFetchResult * assetFetchResult = [PHAsset fetchAssetsInAssetCollection:collection
options:options];
for (PHAsset * asset in assetFetchResult) {
[assetArray addObject:asset];
}
return assetArray;
}
3.获取图片
在PhotoKit中,单个图片的信息都保存在PHAsset中,也可以说每一个PHAsset就是一个图片的所有数据,例如宽、高、图片地址等等。
我们得通过PHAsset来获取图片
PHImageRequestOptions * options = [[PHImageRequestOptions alloc] init];
//图片的质量相关设置
options.resizeMode = PHImageRequestOptionsResizeModeNone;
options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
//当图片为iCloud资源时,是否通过网络获取,默认为NO
options.networkAccessAllowed = YES;
//是否为同步的,默认为NO (这里笔者需要将其顺序加入集合,所以改为了YES)
options.synchronous = YES;
[options setProgressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
// [weakself requestProgress:progress];
}];
_imagesArray = [NSMutableArray array];
for (PHAsset * asset in _currentCollectionData) {
//这个方法的回调是在主线程中回调的
[[PHImageManager defaultManager] requestImageForAsset:asset
targetSize:CGSizeMake(targetSize, targetSize)
contentMode:PHImageContentModeAspectFill
options:options
resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
[_imagesArray addObject:result];
}];
}
这里要特别说明一下targetSize,targetSize是你指定获取图片的大小,一定要按需设置,一般情况下照片都是很大的比如2000*3000,而屏幕的宽度只有375,图片的获取会占用系统资源。当同一时间大批量获取数据时(例如一个相册1000张图片),会耗费较多的时间,可能引发性能问题。
这里稍微展开下笔者的性能的优化问题
场景:相册有2000张图片,以collectionView进行展示,每行四个图片,以6s为例。整屏状态下同时会展示30个图片左右,当极速滑动时,不能有卡顿,且图片展示不发生错误。
笔者尝试过如下两种方法:
1.及时加载图片
2.统一加载图片
刚开始笔者用的第一种方法在Cell中进行加载,所有一切都很正常,但是当滑动稍快时,会有明显卡顿。遂采取了异步加载的方式,卡顿的确是解决了,可图片的展示又发生了问题(当图片获取到时,这时的Cell已经是另一个图片了)。再后来又加上了判断是否为当前图片,经过多次改进,还是会在极速滑动时能感觉到卡顿,陷入了困境。
代码越来越臃肿,越来越复杂,效果却差强人意。我打开了几个巨头的APP,他们的图片加载仿佛是进入选取界面的时候就已经加载好了,连iCloud的图片都没有显示加载的过程。当时觉得只有提前统一加载好了才能达到这种效果,总觉得不科学,直接加载上千张图片性能肯定会有问题。但笔者在第一条路已经绕晕了,也就尝试了下第二种方法,除了量特别大的情况下(数千张时),会有明显的加载过程,其他的时候感觉还不错(心里还是痒痒,有过来人还请不吝赐教)。
顺便列出一个方法,是将一个相册的图片预加载的,理论上可以提升加载图片的速度,具体效果未测:
//load image to cache
PHCachingImageManager * manager = [[PHCachingImageManager alloc] init];
[manager stopCachingImagesForAllAssets];
[manager startCachingImagesForAssets:_currentCollectionData
targetSize:CGSizeMake(targetSize, targetSize)
contentMode:PHImageContentModeAspectFill
options:nil];
4 其他常用方法
取消指定的图片请求:
[[PHImageManager defaultManager] cancelImageRequest:_requestID];
//_requestID为请求图片时的返回,如:
//- (PHImageRequestID)requestImageForAsset:targetSize:contentMode:options:resultHandler:
获取图片的详细信息
PHContentEditingInputRequestOptions * editOptions = [[PHContentEditingInputRequestOptions alloc] init];
editOptions.networkAccessAllowed = NO;
PHContentEditingInputRequestID editID = [self requestContentEditingInputWithOptions:editOptions completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
//是否为iCloud资源
//BOOL isCloud = [info[PHContentEditingInputResultIsInCloudKey] boolValue];
}];
Demo: PJPhotoPicker
singleChoose.gif
mutableChoose.gif
ios+html5+选取照片,iOS 自定义图片选择器 1 - PhotoKit相关推荐
- Android自定义图片选择器
1.前言 随着APP功能的全面化,越来越多的应用都开发了类似微信朋友圈的功能,随时随地分享自己的心情,图片视频!当需要上传图片.视频的时候,就需要一个图片.视频资源选择器,所以接下来将自己实现一个简单 ...
- iOS 开发之照片框架详解
一. 概要 在 iOS 设备中,照片和视频是相当重要的一部分.最近刚好在制作一个自定义的 iOS 图片选择器,顺便整理一下 iOS 中对照片框架的使用方法.在 iOS 8 出现之前,开发者只能使用 A ...
- 猫猫学iOS(四十四)之网易彩票自定义图片在右边的Button_弹出view_ios6,7简单适配...
猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 效果: 注意图里面了吗,其实 ...
- android 仿照ios 图片选择,GitHub - wildma/PictureSelector: Android 图片选择器(仿 IOS 图片选择控件)...
PictureSelector Android 图片选择器(仿 IOS 图片选择控件) 效果图 功能特点 支持通过拍照获取图片 支持通过相册获取图片 支持图片是否裁剪两种场景 支持仿 IOS 底部弹出 ...
- 小红书图片剪裁框架+微信图片选择器+超高清大图预览+图片自定义比例剪裁,支持 UI 自定义、支持跨进程回调
YImagePicker 项目地址:yangpeixing/YImagePicker 简介: 小红书图片剪裁框架+微信图片选择器+超高清大图预览+图片自定义比例剪裁,支持 UI 自定义.支持跨进程回调 ...
- 集小红书图片剪裁+微信图片选择器+自定义图片剪裁于一体的YImagePicker
目录 关于YImagePicker 引入依赖 核心原理 效果图集 点击查看详细API文档 微信图片选择 小红书图片选择 预览 拍照 拍摄视频 调用选择器并剪裁 拍照并剪裁 直接剪裁 提供媒体数据--支 ...
- iOS开发之好用的图片选择第三方TZImagePickerController
最近的项目中涉及到了类似于发布朋友圈的功能,其中就需要上传照片等媒体内容,所以为了方便和效果好看,使用了TZImagePickerController第三方来管理和调用媒体内容,现在就是简单介绍一下这 ...
- 视频聊天源码,IOS 保存图片、视频到自定义相簿
视频聊天源码,IOS 保存图片.视频到自定义相簿实现的相关代码 1.检测相簿以及创建相簿: /** 创建自定义相册 */ +(void)isExistFolder:(NSString * _Nonnu ...
- iOS开发系列--无限循环的图片浏览器
概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件都介绍一遍确实没有必要,所谓授人以鱼不如授 ...
最新文章
- Linux下静态库的创立与使用
- 使用 SAP BTP 创建一个 Spring Boot Java 应用
- 判断二叉树是否是完全二叉树c语言_完全二叉树的节点数,你真的会算吗?
- 三维数学基础(一)坐标系、向量、矩阵
- java使用btree_java数据结构之二叉树遍历的非递归实现
- Fancybox—Fancybox的API和配置选项说明
- python爬虫什么框架好用_推荐十款高效率的Python爬虫框架,你用过几个?
- MAC刻录iso到USB、U盘
- ios开发 各种字体
- iOS音视频理论基础
- 强网杯2021CTF 强网先锋shellcode侧信道攻击复现
- freeredius3.0 mysql_edius插件下载|Edius9滤镜和转场插件Vitascene+蓝宝石插件GenArts Sapphire3.0.257 官方版_ - 极光下载站...
- Photoshop-RGB色彩模式
- OV2640拍摄jpg图像无法解析
- 关于触摸板设备USB映射虚拟桌面的VID与PID
- Vue的双向数据绑定
- TiDB+TiSpark部署--安装,扩缩容及升级操作
- c++实现的阻塞队列
- 摩拜单车,死于创新的一百万种方式
- 负载均衡技术应用介绍
热门文章
- 2021年全国研究生数学建模竞赛华为杯B题空气质量预报二次建模求解全过程文档及程序
- PID专家控制matlab仿真
- 小米平板5.0以上系统如何不root激活xposed框架的经验
- 服务器芯片即将填补中国空白,我国实现无线路由器芯片自研,填补了该领域的技术空白-通信/网络-与非网...
- 通过IP地址和掩码计算地址范围(ipv4/ipv6)
- HTTP HTTPS详解
- java 静态变量 null_Java静态变量变为null
- 注入(4)--消息钩子注入(SetWindowsHookEX)
- JavaScript操作符
- java jackson2.6_Jackson 2 - Convert Java Object to JSON and JSON String to Object