Swift 自定义图片选择器(一) -- PhotosFramework介绍

先上最终效果图:


图片选择器效果图

使用前需要添加该框架,并且在文件头部 import photos

PhotosFramework

首先我们先了解一下PhotosFramework
Work with image and video assets managed by the Photos app, including those from iCloud Photo Library and Live Photos. Fetch and cache full-sized assets or thumbnails asynchronously, revise content, and sync revisions to multiple devices.

处理图像和视频资源,包括iCloud上的网络资源和本地资源。异步获取和缓存资源,保存资源修改,并且将修改同步到所有的设备中。
在这个项目中,我们只需要获取本地资源,并且展示出来。并没有涉及到iCloud和修改资源。

  • PHPhotoLibrary -- 管理照片库访问和更改的共享对象
  1. 用来获取相册的授权情况和请求授权

     let authorizationStatus = PHPhotoLibrary.authorizationStatus()
     switch authorizationStatus {
     case .authorized:
         print("已经授权")
         return true
     case .notDetermined:
         print("不确定是否授权")
         //一般是第一次打开app时的状态
         // 请求授权
         PHPhotoLibrary.requestAuthorization({ (status) in })
     case .denied:
         print("拒绝授权")
     case .restricted:
         print("限制授权")
         break
     }
    
    1. 对照片库进行更改或者是监听相册更改情况。前者应用一般是保存图片、视频等资源到系统相册中(这方面先不深入讨论)。
  • PHAsset 图片、视频等,我们在图片库中最终拿到的某一资源的对象,然后将该对象转换成UIImage,展示出来

    func getImageWithAsset(_ asset: PHAsset, size targetSize: CGSize, finishedCallack: @escaping (_ image: UIImage) -> ()) {
      let options = PHImageRequestOptions()
      options.resizeMode = .exact // 返回图像与目标size保持一致
      options.deliveryMode = .highQualityFormat   // 只返回高像素的图像
      var size = targetSize
      
      // 如果没有目标大小,则返回原图
      if targetSize == .zero {
          size = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
      }
      
      PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .default, options: options) { (image, info) in
          // 如果是image是nil 则直接返回
          guard let image = image else {
              return
          }
          
          // 拿到图片,则返回
          finishedCallack(image)
      }
      }
    

上面的PHImageRequestOptions是用来设置请求图片的相关属性的。
options.resizeMode 表示:如果资源是压缩图片时,系统对图片解码时会参照targetSize的值。

  PHImageRequestOptions
  .fast 返回的图片可能会比targetSize大
  .exact 则与targetSize保持一致。

  options.deliveryMode 有以下取值:
  .opportunistic 会返回一张小图和大图
  .highQualityFormat 只返回大图
  .fastFormat 只返回小图
  • PHAssetCollection 表示PHAsset的集合,包括系统相册,用户创建的相册等。以下是获取智能相册的代码:

    func getSmartAlbums() -> [AlbumItem]? {
      //获取所有的智能相册
      let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
      print("智能相册有\(smartAlbums.count)个")
      let options = PHFetchOptions()
      options.sortDescriptors = [NSSortDescriptor.init(key: "creationDate", ascending: true)]
      
      let albumsArray = getAssetResultInCollection(smartAlbums, fetchOptions: options)
      
      return albumsArray
     }
    
    func getAssetResultInCollection(_ collection: PHFetchResult, fetchOptions options: PHFetchOptions) ->[AlbumItem]? {
      var albumsArray = [AlbumItem]()
      
      for index in 0.. 0 {
              //有照片的相册
              let album = AlbumItem.init(title: assetCollection.localizedTitle, fetchResult: assetFecthResults)
              
              albumsArray.append(album)
          }
      }
      
      return albumsArray
      }
    

结果如下:
Swift 自定义图片选择器(一) -- PhotosFramework介绍_第1张图片
智能相册打印结果

由此可见:smartAlbums是PHAssetCollection,是所有智能相册的集合,而该集合里面的元素assetCollection(表示的是某个智能相册)也是PHAssetCollection,包含的PHAsset就是一张照片。

  • PHCollection 抽象类,PHAssetCollection 和 PHCollectionList的父类,表示PHAsset的集合或者自身的集合。

  • PHCollectionList 表示照片库里面的文件夹,是PHAsset 和自身对象的集合。

  • PHFetchResult 表示有序的图片和图片集合的列表,smartAlbums 的具体类型应该是PHFetchResult, 意思是列表内的元素是PHAssetCollection,一般是用fetch method获取得到的结果。

    let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
    
  • PHFetchOptions 使用fetch method时对结果进行管理的选项,譬如:排序条件,资源类型,是否收藏等。下面是以创建时间升序排序:

    let options = PHFetchOptions()
      options.sortDescriptors = [NSSortDescriptor.init(key: "creationDate", ascending: true)]
    
  • PHImageManager 提供获取图片UIImage对象、视频PlayerItem对象等方法。如果资源需要在界面上展示出来,需要使用该对象获取。
    例如从PHAsset中获取图片:

    PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .default, options: options) { (image, info) in
          // 如果是image是nil 则直接返回
          guard let image = image else {
              return
          }
          
          // 拿到图片,则返回
          finishedCallack(image)
      }

你可能感兴趣的:(Swift 自定义图片选择器(一) -- PhotosFramework介绍)