前言
不知讀者們在平日里使用聊天工具時,有沒有發(fā)表情的習慣。是不是常常在與朋友們聊天時,一言不合就掀起一場斗圖大會呢。小編作為一個喜歡搞事情的小碼農(nóng),上班唯一能放松的事情就是和同事在群里吹牛逼斗斗圖了(不搞點事情代碼怎么吐的動呢)。
找不到圖源,微信表情又有上限等,種種問題讓我施展不出真正的斗圖實力(中毒太深)。非得搞點事情的我計劃開發(fā)一款制作管理GIF表情的相冊,名字叫斗逗圖(目前五菱宏光版正在審核中......)
這波廣告小編打得自己都臉紅了。。。那來切入正題吧,在開發(fā)過程中,我需要通過圖片選擇器選擇多張圖片,可是強大的UIImagePickerController
卻沒有多選功能,這讓我很憂桑,看了看Github,已經(jīng)有比較好的輪子,但樣式固定死了,太花哨了,畢竟咱是五菱宏光,漂移之王,花哨的輪子漂不起來,還是自己用Photos造一個吧。
關于Photos
資源
PHObject:資源基類,PHAsset
、PHCollecton
等都繼承它,它包含了一個屬性localIdentifier
,它是唯一的,所以我們可以通過此屬性來判斷資源對象是否是同一個
PHAsset:代表一個在相冊中的圖片或視頻,它本身并不儲存圖片或視頻資源,它存放的是metaData
,需要通過PHImageManager
來請求才能獲取圖片或視頻資源。
PHCollection:照片庫中單獨輕量不可變的集合對象
PHAssetCollection:PHCollection
的子類,可以通過它獲取系統(tǒng)自帶的相冊信息
PHCollectionList:既是PHCollection
的子類,也是PHCollection
的集合
PHFetchResult:很像NSFetchRequest
吧,它也有predicate
和sortDescriptors
;使用起來,它類似NSArray
,可以通過遍歷獲取儲存的各個元素;還能通過觀察者模式來檢測相冊內(nèi)容是否變化。
獲取資源
PHAssetCollection類方法獲取相冊的資源
#pragma mark - Fetching asset collections
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(nullable PHFetchOptions *)options;
// Smart Albums are not supported, only Albums and Moments
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsContainingAsset:(PHAsset *)asset withType:(PHAssetCollectionType)type options:(nullable PHFetchOptions *)options;
// assetGroupURLs are URLs retrieved from ALAssetGroup's ALAssetsGroupPropertyURL
+ (PHFetchResult<PHAssetCollection *> *)fetchAssetCollectionsWithALAssetGroupURLs:(NSArray<NSURL *> *)assetGroupURLs options:(nullable PHFetchOptions *)options;
#pragma mark - Fetching moment asset collections
+ (PHFetchResult<PHAssetCollection *> *)fetchMomentsInMomentList:(PHCollectionList *)momentList options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAssetCollection *> *)fetchMomentsWithOptions:(nullable PHFetchOptions *)options;
PHAsset類方法獲取分類過后的資源
#pragma mark - Fetching assets
+ (PHFetchResult<PHAsset *> *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
+ (nullable PHFetchResult<PHAsset *> *)fetchKeyAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithBurstIdentifier:(NSString *)burstIdentifier options:(nullable PHFetchOptions *)options;
// Fetches PHAssetSourceTypeUserLibrary assets by default (use includeAssetSourceTypes option to override)
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithOptions:(nullable PHFetchOptions *)options;
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithMediaType:(PHAssetMediaType)mediaType options:(nullable PHFetchOptions *)options;
// assetURLs are URLs retrieved from ALAsset's ALAssetPropertyAssetURL
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithALAssetURLs:(NSArray<NSURL *> *)assetURLs options:(nullable PHFetchOptions *)options;
返回的類型都是PHFetchResult
,里面存放的并不是一個個的圖片原始資源,而只是一個個包含元數(shù)據(jù)的PHAsset
。那我們該如何獲取圖片的原始資源呢?這就該用到PHImageManager
類。
請求資源
PHImageManager
此類提供了請求加載圖片或視頻數(shù)據(jù)的方法,既可以獲取原始大小的圖片,也能獲取縮略圖,同時也可以取回用作播放的AVFoundation相關對象或者操作視頻資源。
當同時加載多個資源很快顯示出來時, 可以使用PHCachingImageManager
類預加載圖片至緩存,這個會在之后的文章中寫到。
以下方法都是實例方法,調用時需要使用defaultManager
請求圖片
方法列表:
#pragma mark - Image
- (PHImageRequestID)requestImageForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHImageRequestOptions *)options resultHandler:(void (^)(UIImage *__nullable result, NSDictionary *__nullable info))resultHandler;
// resultHandler for asynchronous requests, always called on main thread
- (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options resultHandler:(void(^)(NSData *__nullable imageData, NSString *__nullable dataUTI, UIImageOrientation orientation, NSDictionary *__nullable info))resultHandler;
//請求方法都返回了PHImageRequestID,可以通過此ID來取消請求
- (void)cancelImageRequest:(PHImageRequestID)requestID;
targetSize
目標尺寸
contentMode
如果資源的比例與所給的目標大小不匹配的話,contentMode
決定了圖片如何改變
(詳細可看PHImageRequestOptionsDeliveryMode和PHImageRequestOptionsResizeMode)
**PHImageContentModeAspectFit**:使圖片根據(jù)目標大小完整顯示
**PHImageContentModeAspectFill**:使圖片根據(jù)目標大小裁剪顯示
**PHImageContentModeDefault**: 當尺寸設置為```PHImageManagerMaximumSize```時使用```PHImageContentModeDefault```,得到的結果沒有經(jīng)過縮放和裁剪
options
-
version:
當version
等于PHImageRequestOptionsVersionCurrent
請求返回資源是已經(jīng)調整過后最大的圖片數(shù)據(jù) -
synchronous:
請求是否同步執(zhí)行,值為NO
時,會根據(jù)deliveryMode
這個屬性,等待方法的回調;當為YES
時,deliveryMode
的值會被忽略,resultHandler
這個回調也只會執(zhí)行一次 - resizeMode:圖像變化方式。
Fast:盡快地提供接近要求的尺寸;
Exact:精準提供要求的尺寸。
deliveryMode:圖像質量。
Opportunistic:臨時圖像;
HighQualityFormat:高質量圖像;
FastFormat,以最快速度提供好的質量。 這個屬性只有在 synchronous 為 true 時有效。
-
normalizedCropRect:
用于對原始尺寸的圖像進行裁剪,基于比例坐標。只在resizeMode
為Exact
時有效。
resultHandler
此代碼塊是異步執(zhí)行的,如果deliveryMode
等于PHImageRequestOptionsDeliveryModeOpportunistic
時,先會同步返回一個臨時的低質量資源,之后當請求到所需的圖片資源時,會異步返回;options
參數(shù)的作用就是來定制這些行為
請求LivePhoto
請求LivePhoto資源。如果 PHLivePhotoRequestOptions
的deliveryMode
為PHImageRequestOptionsDeliveryModeOpportunistic
或者options
為nil
時,resultHandler
回調不止一次,并且有可能會在同步方法返回前先返回
resultHandler
回調代碼塊的Info
字典PHImageResultIsDegradedKey
對應的值代表是否低質量的LivePhoto已經(jīng)提供
#pragma mark - Live Photo
//Live Photo
- (PHImageRequestID)requestLivePhotoForAsset:(PHAsset *)asset targetSize:(CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:(nullable PHLivePhotoRequestOptions *)options resultHandler:(void (^)(PHLivePhoto *__nullable livePhoto, NSDictionary *__nullable info))resultHandler NS_AVAILABLE_IOS(9_1);
請求視頻
#pragma mark - Video
//可播放視頻音頻資源
- (PHImageRequestID)requestPlayerItemForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVPlayerItem *__nullable playerItem, NSDictionary *__nullable info))resultHandler;
// 導出會話
- (PHImageRequestID)requestExportSessionForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options exportPreset:(NSString *)exportPreset resultHandler:(void (^)(AVAssetExportSession *__nullable exportSession, NSDictionary *__nullable info))resultHandler;
// 其他
- (PHImageRequestID)requestAVAssetForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVAsset *__nullable asset, AVAudioMix *__nullable audioMix, NSDictionary *__nullable info))resultHandler;
觀察相冊變更
相冊里多了一張照片,如何及時的顯示出來呢?
此時PHPhotoLibraryChangeObserver的作用就體現(xiàn)出來了
顧名思義,它就類似一個觀察者,監(jiān)測變化,反應變化。
使用步驟:
- 添加此協(xié)議
<PHPhotoLibraryChangeObserver>
- (void)viewWillAppear:(BOOL)animated {
//注冊觀察相冊變化的觀察者
[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];
}
- (void)dealloc {
//銷毀觀察相冊變化的觀察者
[[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self];
}
2.實現(xiàn)協(xié)議
- (void)photoLibraryDidChange:(PHChange *)changeInstance;
PHChange
的changeDetailsForFetchResult:
方法檢測照片集合內(nèi)是否產(chǎn)生變化,入?yún)楸粰z測的照片集合
- (nullable PHFetchResultChangeDetails *)changeDetailsForFetchResult:(PHFetchResult *)object;
結束語
以上是關于Photos框架的簡單介紹,一些基本的用法,足夠開發(fā)一款簡單的相冊或者選擇器啦!
這回買好零件,下一篇就開始造我們五菱宏光專屬輪子了。
敬請期待~
小編對文檔的理解可能會有些出入,有錯誤希望讀者能積極指出,我會及時更正。
如果喜歡,請持續(xù)關注,順便點個喜歡噢??????