上一篇简单的介绍了一下Photos,下面就开始介绍demo里面的业务类。
相册列表项
表示一个非空的相册,即非空的PHAsset资源的集合。主要用于显示图片列表,并且在选中某一列表时,显示该相册里面的图片资源。
/// 相簿列表项
struct AlbumItem {
var title : String? // 相册的标题
var fetchResult : PHFetchResult<PHAsset> // 资源集合
init(title: String?, fetchResult: PHFetchResult<PHAsset>) {
self.title = title
self.fetchResult = fetchResult
}
}
重载运算符 +
AlbumItem 是自定义的数据类型,为了实现该类型的数组相加,需要重载运算符,然后就可以像其他数据类型一样直接使用符号 “+” 来合并两个数组。(重载运算符需要在全局域中,就是跟AlbumItem在同一层级下)
postfix operator +
func + (left: [AlbumItem]?, right: [AlbumItem]?) ->[AlbumItem]? {
if (left == nil) {
return right
}
if (right == nil) {
return left
}
var result = left!
for (_, item) in right!.enumerated() {
result.append(item)
}
return result
}
PickerHelper 图片资源获取帮助类
所有的关于图片资源获取的方法都封装在PickerHelper里面,并且使用单例设计模式,设置成单例类。
/// 获取图片的资源的类
class PickerHelper: NSObject {
static let helperDefault : PickerHelper = {
let helper = PickerHelper()
return helper
}()
var targetSize = CGSize(width: 320, height: 675) // 默认大图的大小
var maxCount = 9 // 默认最多可选9张图片
}
targetSize 和maxCount 公开可变,是让用户可以根据需要进行修改。
获取相册数组
/// 获取智能相册
///
/// - returns: 智能相册数组 PHFetchResult<PHAsset>
func getSmartAlbums() -> [AlbumItem]? {
//获取所有的智能相册
let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
// 获取资源选项设置,以创建时间升序排序
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor.init(key: "creationDate", ascending: true)]
let albumsArray = getAssetResultInCollection(smartAlbums, fetchOptions: options)
return albumsArray
}
/// 从PHAssetCollection中获取相册,主要是用于相册列表
///
/// - parameter collection: 相册集合
/// - parameter options: 获取相册的相关设置参数
///
/// - returns: 相册数组
private func getAssetResultInCollection(_ collection: PHFetchResult<PHAssetCollection>, fetchOptions options: PHFetchOptions) ->[AlbumItem]? {
var albumsArray = [AlbumItem]()
for index in 0..<collection.count {
//获取一个相册
let assetCollection = collection[index];
//然后从每一个智能相册中获取资源,获取到的是一个list
let assetFecthResults = PHAsset.fetchAssets(in: assetCollection, options: nil);
print("\(assetCollection.localizedTitle!)相册,共有照片数:\(assetFecthResults.count)")
if assetFecthResults.count > 0 {
//有照片的相册
let album = AlbumItem.init(title: assetCollection.localizedTitle, fetchResult: assetFecthResults)
albumsArray.append(album)
}
}
return albumsArray
}
获取用户创建的相册数组
/// 获取用户创建的相册
///
/// - returns: 相册数组
func getUserAlbums() -> [AlbumItem]? {
let userAlbums = PHCollectionList.fetchTopLevelUserCollections(with: nil) as! PHFetchResult<PHAssetCollection>
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor.init(key: "creationDate", ascending: true)]
let albumsArray = getAssetResultInCollection(userAlbums, fetchOptions: options)
return albumsArray
}
PictureItem
表示一个图片资源,并且保存了获取到的大图、小图和该资源是否被选中
class PictureItem: NSObject {
/// 图片资源
var asset = PHAsset()
/// 显示的小图
var lowImage: UIImage?
/// 上传的大图
var hightImage: UIImage?
/// 是否选中的标志
var isSelected = false
init(asset: PHAsset, lowImage: UIImage?, hightImage: UIImage?, isSelected: Bool = false) {
self.asset = asset
self.lowImage = lowImage
self.hightImage = hightImage
self.isSelected = isSelected
}
}
获取相册的图片
/// 获取某个相册里面的图片资源
///
/// - parameter albumItem: 相册
///
/// - returns: 图片数组 [PictureItem]
func getPicturesInAlbumItem(_ albumItem: AlbumItem) -> [PictureItem] {
var pictures = [PictureItem]()
albumItem.fetchResult.enumerateObjects({ (asset, curIndex, nil) in
pictures.append(PictureItem.init(asset: asset, lowImage: nil, hightImage: nil))
})
return pictures
}
/// 从图片资源PHAsset中获取指定大小的image对象
///
/// - parameter asset: Asset图片资源
/// - parameter targetSize: 指定尺寸
/// - parameter finishedCallack: 获取后返回的block
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)
}
}