前言
不知讀者們?cè)谄饺绽锸褂昧奶旃ぞ邥r(shí)礁凡,有沒有發(fā)表情的習(xí)慣。是不是常常在與朋友們聊天時(shí)慧妄,一言不合就掀起一場(chǎng)斗圖大會(huì)呢顷牌。小編作為一個(gè)喜歡搞事情的小碼農(nóng),上班唯一能放松的事情就是和同事在群里吹牛逼斗斗圖了(不搞點(diǎn)事情代碼怎么吐的動(dòng)呢)腰涧。
找不到圖源韧掩,微信表情又有上限等,種種問題讓我施展不出真正的斗圖實(shí)力(中毒太深)窖铡。非得搞點(diǎn)事情的我計(jì)劃開發(fā)一款制作管理GIF表情的相冊(cè)疗锐,名字叫斗逗圖(目前五菱宏光版正在審核中......)
這波廣告小編打得自己都臉紅了。费彼。滑臊。那來切入正題吧,在開發(fā)過程中箍铲,我需要通過圖片選擇器選擇多張圖片雇卷,可是強(qiáng)大的UIImagePickerController
卻沒有多選功能,這讓我很憂桑,看了看Github关划,已經(jīng)有比較好的輪子小染,但樣式固定死了,太花哨了贮折,畢竟咱是五菱宏光裤翩,漂移之王,花哨的輪子漂不起來调榄,還是自己用Photos造一個(gè)吧踊赠。
關(guān)于Photos
資源
PHObject:資源基類,PHAsset
每庆、PHCollecton
等都繼承它筐带,它包含了一個(gè)屬性localIdentifier
,它是唯一的缤灵,所以我們可以通過此屬性來判斷資源對(duì)象是否是同一個(gè)
PHAsset:代表一個(gè)在相冊(cè)中的圖片或視頻伦籍,它本身并不儲(chǔ)存圖片或視頻資源,它存放的是metaData
,需要通過PHImageManager
來請(qǐng)求才能獲取圖片或視頻資源腮出。
PHCollection:照片庫中單獨(dú)輕量不可變的集合對(duì)象
PHAssetCollection:PHCollection
的子類鸽斟,可以通過它獲取系統(tǒng)自帶的相冊(cè)信息
PHCollectionList:既是PHCollection
的子類,也是PHCollection
的集合
PHFetchResult:很像NSFetchRequest
吧利诺,它也有predicate
和sortDescriptors
;使用起來剩燥,它類似NSArray
慢逾,可以通過遍歷獲取儲(chǔ)存的各個(gè)元素;還能通過觀察者模式來檢測(cè)相冊(cè)內(nèi)容是否變化灭红。
獲取資源
PHAssetCollection類方法獲取相冊(cè)的資源
#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
侣滩,里面存放的并不是一個(gè)個(gè)的圖片原始資源,而只是一個(gè)個(gè)包含元數(shù)據(jù)的PHAsset
变擒。那我們?cè)撊绾潍@取圖片的原始資源呢君珠?這就該用到PHImageManager
類。
請(qǐng)求資源
PHImageManager
此類提供了請(qǐng)求加載圖片或視頻數(shù)據(jù)的方法娇斑,既可以獲取原始大小的圖片策添,也能獲取縮略圖,同時(shí)也可以取回用作播放的AVFoundation相關(guān)對(duì)象或者操作視頻資源毫缆。
當(dāng)同時(shí)加載多個(gè)資源很快顯示出來時(shí)唯竹, 可以使用PHCachingImageManager
類預(yù)加載圖片至緩存,這個(gè)會(huì)在之后的文章中寫到苦丁。
以下方法都是實(shí)例方法浸颓,調(diào)用時(shí)需要使用defaultManager
請(qǐng)求圖片
方法列表:
#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;
//請(qǐng)求方法都返回了PHImageRequestID,可以通過此ID來取消請(qǐng)求
- (void)cancelImageRequest:(PHImageRequestID)requestID;
targetSize
目標(biāo)尺寸
contentMode
如果資源的比例與所給的目標(biāo)大小不匹配的話,contentMode
決定了圖片如何改變
(詳細(xì)可看PHImageRequestOptionsDeliveryMode和PHImageRequestOptionsResizeMode)
**PHImageContentModeAspectFit**:使圖片根據(jù)目標(biāo)大小完整顯示
**PHImageContentModeAspectFill**:使圖片根據(jù)目標(biāo)大小裁剪顯示
**PHImageContentModeDefault**: 當(dāng)尺寸設(shè)置為```PHImageManagerMaximumSize```時(shí)使用```PHImageContentModeDefault```产上,得到的結(jié)果沒有經(jīng)過縮放和裁剪
options
-
version:
當(dāng)version
等于PHImageRequestOptionsVersionCurrent
請(qǐng)求返回資源是已經(jīng)調(diào)整過后最大的圖片數(shù)據(jù) -
synchronous:
請(qǐng)求是否同步執(zhí)行棵磷,值為NO
時(shí),會(huì)根據(jù)deliveryMode
這個(gè)屬性晋涣,等待方法的回調(diào)仪媒;當(dāng)為YES
時(shí),deliveryMode
的值會(huì)被忽略姻僧,resultHandler
這個(gè)回調(diào)也只會(huì)執(zhí)行一次 - resizeMode:圖像變化方式规丽。
Fast:盡快地提供接近要求的尺寸;
Exact:精準(zhǔn)提供要求的尺寸撇贺。
deliveryMode:圖像質(zhì)量赌莺。
Opportunistic:臨時(shí)圖像;
HighQualityFormat:高質(zhì)量圖像松嘶;
FastFormat艘狭,以最快速度提供好的質(zhì)量。 這個(gè)屬性只有在 synchronous 為 true 時(shí)有效翠订。
-
normalizedCropRect:
用于對(duì)原始尺寸的圖像進(jìn)行裁剪巢音,基于比例坐標(biāo)。只在resizeMode
為Exact
時(shí)有效尽超。
resultHandler
此代碼塊是異步執(zhí)行的官撼,如果deliveryMode
等于PHImageRequestOptionsDeliveryModeOpportunistic
時(shí),先會(huì)同步返回一個(gè)臨時(shí)的低質(zhì)量資源似谁,之后當(dāng)請(qǐng)求到所需的圖片資源時(shí)傲绣,會(huì)異步返回;options
參數(shù)的作用就是來定制這些行為
請(qǐng)求LivePhoto
請(qǐng)求LivePhoto資源巩踏。如果 PHLivePhotoRequestOptions
的deliveryMode
為PHImageRequestOptionsDeliveryModeOpportunistic
或者options
為nil
時(shí)秃诵,resultHandler
回調(diào)不止一次,并且有可能會(huì)在同步方法返回前先返回
resultHandler
回調(diào)代碼塊的Info
字典PHImageResultIsDegradedKey
對(duì)應(yīng)的值代表是否低質(zhì)量的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);
請(qǐng)求視頻
#pragma mark - Video
//可播放視頻音頻資源
- (PHImageRequestID)requestPlayerItemForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVPlayerItem *__nullable playerItem, NSDictionary *__nullable info))resultHandler;
// 導(dǎo)出會(huì)話
- (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;
觀察相冊(cè)變更
相冊(cè)里多了一張照片塞琼,如何及時(shí)的顯示出來呢菠净?
此時(shí)PHPhotoLibraryChangeObserver的作用就體現(xiàn)出來了
顧名思義,它就類似一個(gè)觀察者彪杉,監(jiān)測(cè)變化毅往,反應(yīng)變化。
使用步驟:
- 添加此協(xié)議
<PHPhotoLibraryChangeObserver>
- (void)viewWillAppear:(BOOL)animated {
//注冊(cè)觀察相冊(cè)變化的觀察者
[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];
}
- (void)dealloc {
//銷毀觀察相冊(cè)變化的觀察者
[[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self];
}
2.實(shí)現(xiàn)協(xié)議
- (void)photoLibraryDidChange:(PHChange *)changeInstance;
PHChange
的changeDetailsForFetchResult:
方法檢測(cè)照片集合內(nèi)是否產(chǎn)生變化派近,入?yún)楸粰z測(cè)的照片集合
- (nullable PHFetchResultChangeDetails *)changeDetailsForFetchResult:(PHFetchResult *)object;
結(jié)束語
以上是關(guān)于Photos框架的簡(jiǎn)單介紹煞抬,一些基本的用法,足夠開發(fā)一款簡(jiǎn)單的相冊(cè)或者選擇器啦构哺!
這回買好零件革答,下一篇就開始造我們五菱宏光專屬輪子了战坤。
敬請(qǐng)期待~
小編對(duì)文檔的理解可能會(huì)有些出入,有錯(cuò)誤希望讀者能積極指出残拐,我會(huì)及時(shí)更正途茫。
如果喜歡,請(qǐng)持續(xù)關(guān)注溪食,順便點(diǎn)個(gè)喜歡噢??????