上一篇簡單的介紹了一下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)
}
}