iOS开发进阶 - 基于PhotoKit的图片选择器
移动端访问不佳,请访问我的个人博客
很早之前就用OC把代码写完了并用在项目中了,一直没时间整理,现在用swift重写一份,并且更加详细的来了解这个Photos框架,下面是我集合苹果官方文档和其他大神的博客写出的一篇关于Photos框架的介绍
老规矩先上效果图和Demo地址:

了解Photos框架
Photos是ios8出的一个新的图片选择框架,取代之前的AssetsLibrary框架,相比较AssetsLibrary框架Photos的用法更加灵活,发现在iOS9中AssetsLibrary已经被弃用了,并且也不支持livePhoto,iOS9上再使用AssetsLibrary框架时还有个严重的问题就是图片分辨率会变的很低,这篇文章主要讲解一下Photos的简单用法,用它做一个简单的图片选择器。
Photos中各个类的简单解释:
| 类名 | 作用 |
|---|---|
| PHAdjustmentData | 当用户编辑资源,照片与修改后的图像或视频数据保存在一个PHAdjustmentData对象中 |
| PHAsset | 代表照片库中的一个资源实体,可以理解为一张照片,在打印的时候,可以清楚的看见里面包含了照片的时间、标题等信息 |
| PHAssetChangeRequest | 使用PHAssetChangeRequest对象来创建、删除和修改相片库里面的PHAsset对象 |
| PHAssetCollectionChangeRequest | 使用PHAssetCollectionChangeRequest对象来创建、删除和修改相片库里面的PHAssetCollection对象 |
| PHAssetCreationRequest | 使用PHAssetCreationRequest对象构造一个新的照片或视频,并将其添加到照片库 |
| PHAssetResource | 一个PHAssetResource对象表示在照片库中的照片或视频资源(也就是一个PHAsset对象)相关联的基础数据资源之一,使用PHAssetResourceManager类获取它 |
| PHAssetResourceManager | PHAssetResourceManager对象提供了访问与照片资源相关的资源基础数据存储方法 |
| PHChange | PHChange对象来通知的照片库中的资源的一些变法,比如增加和删除 |
| PHCollection | PHAssetCollection对象表示一组照片或视频资源。包括时刻和相册中可见照片应用,以及特殊的集合,如共享照片流。 |
| PHCollectionListChangeRequest | 使用PHCollectionListChangeRequest对象在一个照片库中创建、删除或修改PHCollectionList对象。 |
| PHContentEditingInput | PHContentEditingInput对象描述资产用于编辑元数据 |
| PHContentEditingOutput | PHContentEditingOutput对象表示编辑照片资产的照片或视频内容的结果 |
| PHFetchOptions | 获取资源时的检索参数,可以传 nil,即使用系统默认值 |
| PHFetchResult | 通过PHFetchResult来获取照片实体的有序列表 |
| PHImageManager | PHImageManager对象提供用于加载与PHAsset对象相关联的图像或视频数据的方法。使用这些方法来获取全尺寸照片资产或缩略图,或者检索AV Foundation对象播放,导出和操纵的视频资产。 |
| PHLivePhoto | 用来获取LivePhoto实体 |
| PHObject | 照片等实体的抽象类 |
| PHPhotoLibrary | PHPhotoLibrary对象表示用户的照片库整套资源和收藏的照片,包括存储在本地设备上在iCloud的照片对象。 |
| PhotosTypes | 与Photos框架相关的类型的枚举 |
获取相册列表
获取相册列表可以需要用到一下类:
- PHFetchOptions:对象检索的对象,可以对相册列表进行筛选
- PHAssetCollection:图片集合的对象,筛选后获得的集合
下面是获取相册列表的代码片段:
//MARK: 属性列表
//全部相册的数组
private(set) var photoAlbums = [[String: PHFetchResult<PHAsset>]]()
private(set) var selectPhotoArr = [PHAsset]()
//是否同步请求图片
public var isSynchronous: Bool = false {
didSet{
self.photoOption.isSynchronous = isSynchronous
}
}
//MARK: 初始化方法
override init() {
super.init()
//图片请求设置成快速获取
self.photoOption.resizeMode = .fast
self.photoOption.deliveryMode = .opportunistic
getPhotoAlbum()
}
/**
开始获取获取相册列表
*/
private func getPhotoAlbum() {
//创建一个PHFetchOptions对象检索照片
let options = PHFetchOptions()
//通过创建时间来检索
options.sortDescriptors = [NSSortDescriptor.init(key: photoCreationDate, ascending: false)]
//通过数据类型来检索,这里为只检索照片
options.predicate = NSPredicate.init(format: "mediaType in %@", [PHAssetMediaType.image.rawValue])
//通过检索条件检索出符合检索条件的所有数据,也就是所有的照片
let allResult = PHAsset.fetchAssets(with: options)
//获取用户创建的相册
let userResult = PHAssetCollection.fetchTopLevelUserCollections(with: nil)
//获取智能相册
let smartResult = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
//将获取的相册加入到相册的数组中
photoAlbums.append([WCLImagePickerBundle.localizedString(key: "全部照片"): allResult])
userResult.enumerateObjects(options: .concurrent) { (collection, index, stop) in
let assetcollection = collection as! PHAssetCollection
//通过检索条件从assetcollection中检索出结果
let assetResult = PHAsset.fetchAssets(in: assetcollection, options: options)
if assetResult.count != 0 {
self.photoAlbums.append([assetcollection.localizedTitle!:assetResult])
}
}
smartResult.enumerateObjects(options: .concurrent) { (collection, index, stop) in
//通过检索条件从assetcollection中检索出结果
let assetResult = PHAsset.fetchAssets(in: collection, options: options)
if assetResult.count != 0 {
self.photoAlbums.append([collection.localizedTitle!:assetResult])
}
}
}
获取某个相册的所有图片列表
需要用到的类:
- PHFetchResult:对象检索的对象,可以对图片进行筛选
- PHAsset:图片资源的对象,代表一个图片或者视频资源
下面贴代码片段:
/**
通过下标返回相册的PHFetchResult
- parameter index: 选择相册的index
- returns: 相册的PHFetchResult
*/
public func getAblumResult(_ ablumIndex: Int) -> PHFetchResult<PHAsset>? {
if let ablum = self.photoAlbums[wcl_safe: ablumIndex] {
if let result = ablum.values.first {
return result
}
}
return nil
}
上面代码中返回的result就代表选中的相册的图片列表
获取到单张图片的数据
通过上面获取到的相册的图片列表通过下标就能获得到图片对应的PHAsset,需要用到的类:
- PHCachingImageManager:获取图片数据的Manager,也可缓存数据
- PHImageRequestOptions:获取图片的一些选项配置,比如获取方式等等
- PHAsset:图片资源的对象,代表一个图片或者视频资源
下面是代码片段:
/**
根据PHAsset获取photo
- parameter ablumIndex: 相册的index
- parameter alasset: 相册里图片的PHAsset
- parameter photoSize: 图片的size
- parameter resultHandler: 返回照片的回调
*/
public func getPhoto(_ photoSize: CGSize, alasset: PHAsset?, resultHandler: ((UIImage?, [AnyHashable: Any]?) -> Void)?) {
if alasset != nil {
let scale = UIScreen.main.scale
let photoScaleSize = CGSize(width: photoSize.width*scale, height: photoSize.height*scale)
self.photoManage.requestImage(for: alasset!, targetSize: photoScaleSize, contentMode: .aspectFill, options: self.photoOption, resultHandler: { (image, infoDic) in
if image != nil {
resultHandler?(image, infoDic)
}else {
//没获取到返回默认图片
let image_buffer = WCLImagePickerBundle.imageFromBundle("image-buffer")
resultHandler?(image_buffer, infoDic)
}
})
}
}
将图片存入相册
有时候我们需要将应用里的图片存到相册里面,一下是会用到的类:
- PHPhotoLibrary:代表我们手机中的图片库,用它来操作图片库中的图片
- PHAssetChangeRequest:资源操作的请求类,用来对资源进行操作
代码片段:
//执行变化
PHPhotoLibrary.shared().performChanges({
//创建一个图片资源
PHAssetChangeRequest.creationRequestForAsset(from: image)
}, completionHandler: { (flag, error) in
//执行结果回调
})
总结
以上简单的讲解了一下Photos相关知识点和使用方法,更多的可以去官方文档上去查看。用Photos自己写了一个图片选择器,大家有兴趣的可以去看一下,有用的话可以star一下,写不不是很好,有什么错误可以指出来~最后谢谢大家的阅读。
iOS开发进阶 - 基于PhotoKit的图片选择器的更多相关文章
- iOS开发进阶
<iOS开发进阶>基本信息作者: 唐巧 出版社:电子工业出版社ISBN:9787121247453上架时间:2014-12-26出版日期:2015 年1月开本:16开页码:268版次:1- ...
- iOS开发系列--无限循环的图片浏览器
--UIKit之UIScrollView 概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件 ...
- iOS开发进阶(唐巧)读书笔记(一)
如何提高iOS开发技能 1.阅读博客:https://github.com/tangqiaoboy/iOSBlogCN 40多位iOS开发博主的博客地址 2.读书:每年阅读一本高质量的iOS开发书籍 ...
- 《iOS开发进阶》书籍目录
第一部分:iOS开发工具 第二部分:iOS开发实践 第10章 理解内存管理 10.1 引用计数 10.1.1 什么是引用计数,原理是什么 10.1.2 我们为什么需要引用计数 10.1.3 不要向已经 ...
- iOS开发进阶--1.多线程简介
学习是由已知的知识模型推理未知的知识模型的的过程. 本文适合学习完objective-c基础,想进一步提高做iOS开发的同学阅读. 在说线程的时候,我们先看看进程. 1.进程 每一个运行在系统中的应用 ...
- iOS开发进阶之 UIWebView
刚接触IOS开发1年多,现在对于混合式移动端开发越来越流行,因为开发成本上.速度上都比传统的APP开发要好,混合式开发是传统模式与PC网页端相结合的模式.那么提到了 APP的混合模式开发,在Andro ...
- 【原】iOS开发进阶(唐巧)读书笔记(二)
第三部分:iOS开发底层原理 1.Objective-C对象模型 1.1 isa指针 NSObject.h部分代码: NS_ROOT_CLASS @interface NSObject <NSO ...
- Android开发之高仿微信图片选择器
记得刚开始做Andriod项目那会,经常会碰到一些上传图片的功能需求,特别是社交类的app,比如用户头像,说说配图,商品配图等功能都需要让我们到系统相册去选取图片,但官方却没有提供可以选取多张图片的相 ...
- iOS开发项目实战——Swift实现图片轮播与浏览
近期開始开发一个新的iOS应用,自己决定使用Swift.进行了几天之后,发现了一个非常严峻的问题.那就是无论是书籍,还是网络资源,关于Swift的实在是太少了,随便一搜全都是OC实现某某某功能.就算是 ...
随机推荐
- 第十课——cluster故障转移操作,codis部署
作业描述] 1.cluster的故障转移操作,截图展示 2.部署codis,并写代码访问codis ================================================== ...
- elasticsearch的store属性 vs _source字段
众所周知_source字段存储的是索引的原始内容,那store属性的设置是为何呢?es为什么要把store的默认取值设置为no?设置为yes是否是重复的存储呢? 我们将一个field的值写入es中,要 ...
- 简单JS旋转实现转盘抽奖效果
闲来没事,做了一个模拟转盘抽奖的HTML&JS的效果: 可以在设置的时候,选择几个区域,并且可以填写指针将要停止的区域 比如,我选择了"区域2",结果就是这样 具体可以见下 ...
- 数据结构(java语言描述)
概念性描述与<数据结构实例教程>大同小异,具体参考:http://www.cnblogs.com/bookwed/p/6763300.html. 概述 基本概念及术语 数据 信息的载体,是 ...
- 剑指Offer——数字在排序数组中出现的次数
题目描述: 统计一个数字在排序数组中出现的次数. 分析: 二分变形.二分查找最左边和最右边k的位置,然后相减加一就是结果. 代码: class Solution { public: int GetNu ...
- libtorch 哪些函数比较常用?
libtorch 加载 pytorch 模块进行预测示例 void mat2tensor(const char * path, torch::Tensor &output) { //读取图片 ...
- Python面试应急5分钟!
不论你是初入江湖,还是江湖老手,只要你想给自己一个定位那就少不了面试!面试的重要性相信大家都知道把,这就是我们常说的“第一印象”,给大家说一下我的面试心得把,面试前的紧张是要的,因为这能让你充分准 ...
- 【转载】ARM MMU详解
一.MMU的产生 许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以内存容量虽然小,但还是可以 ...
- Docker给运行中的容器添加映射端口
方法一: 1.获得容器IP将container_name 换成实际环境中的容器名docker inspect `container_name` | grep IPAddress 2. iptables ...
- ED3 flash 、OBP flash
海力士.东芝等ED3 NAND Flash ED3的TLC编程规则相对于OBP来讲会简单许多,因为ED3的编程规则非常有规律,很容易掌握,ED3的每个WL页数量是固定的. ED3在对行地址的定义上与O ...