iOS 基於PhotoKit框架的自定義相冊

尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️

加入LINE好友

作者丨楓developer

https://www.jianshu.com/p/687157a50426

今天給大家講一個乾貨,簡單實用。之前公司的項目需要自定義相冊,並且需要獲取圖片的經緯度信息,使用UIImagePickerController自然是做到不了的。所以就用到了我們今天所說的PhotoKit框架,因為PhotoKit是iOS8之後出的,所以iOS8以前的項目是不能使用的(可以使用AssetsLibrary,這里就不多介紹了)。

iOS 基於PhotoKit框架的自定義相冊

先來介紹一下PhotoKit的主要屬性:

1.PHPhotoLibrary

官方解釋:PHPhotoLibrary提供對用戶照片庫中的照片、視頻和相關內容的元數據和圖像數據的訪問,包括來自照相機輥、iCloud共享、照片流、從iTunes導入和同步的內容。

簡單的說就是提供了,獲取用戶是否已經開通訪問相冊的權限。

[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {

if(status == PHAuthorizationStatusAuthorized) {

/// 用戶開通了權限

} else{

/// 用戶沒有開通權限

}

}];

///這里是PHAuthorizationStatus的所有枚舉參數

typedefNS_ENUM( NSInteger, PHAuthorizationStatus) {

PHAuthorizationStatusNotDetermined = 0, // 用戶尚未作出關於這個應用的選擇。

PHAuthorizationStatusRestricted, // 此應用程序未被授權訪問照片數據。

// 用戶可能無法更改此應用程序的狀態,可能是由於活動限制

// 比如家長控制。

PHAuthorizationStatusDenied, // 用戶已明確拒絕此應用程序訪問照片數據。

PHAuthorizationStatusAuthorized // 用戶已授權此應用程序訪問照片數據。

}

2. PHAssetCollection

繼承於PHCollection,它最主要的功能就是獲取到對應的相冊。通過相冊我們就可以獲取相冊中的圖片了。

這里是他最常用的方法:

// 通過這個方法以及PHAssetCollectionType和PHAssetCollectionSubtype參數,就能獲取你想要的相冊了。(下面我能翻譯多少就翻譯多少)

+ (PHFetchResult *)fetchAssetCollectionsWithType:(PHAssetCollectionType)type subtype:(PHAssetCollectionSubtype)subtype options:(nullable PHFetchOptions *)options;

// PHAssetCollectionType的所有參數

typedef NS_ENUM(NSInteger, PHAssetCollectionType) {

PHAssetCollectionTypeAlbum = 1, // 相冊,系統外的

PHAssetCollectionTypeSmartAlbum = 2, // 智能相冊,系統自己分配和歸納的

PHAssetCollectionTypeMoment = 3, // 時刻,系統自動通過時間和地點生成的分組

} PHOTOS_ENUM_AVAILABLE_IOS_TVOS( 8_0, 10_0);

typedef NS_ENUM(NSInteger, PHAssetCollectionSubtype) {

// PHAssetCollectionTypeAlbum regular subtypes

PHAssetCollectionSubtypeAlbumRegular = 2, // 在iPhone中自己創建的相冊

PHAssetCollectionSubtypeAlbumSyncedEvent = 3,

PHAssetCollectionSubtypeAlbumSyncedFaces = 4, // 從圖片app中導入的人物照片

PHAssetCollectionSubtypeAlbumSyncedAlbum = 5, // 從圖片app導入的相冊

PHAssetCollectionSubtypeAlbumImported = 6,

// PHAssetCollectionTypeAlbum shared subtypes

PHAssetCollectionSubtypeAlbumMyPhotoStream = 100, // 照片流,照片流和iCloud有關,如果在設置里關閉了iCloud開關,就獲取不到了

PHAssetCollectionSubtypeAlbumCloudShared = 101, // iCloud的共享相冊,點擊照片上的共享tab創建後就能拿到了,但是前提是你要在設置中打開iCloud的共享開關(打開後才能看見共享tab)

// PHAssetCollectionTypeSmartAlbum subtypes

PHAssetCollectionSubtypeSmartAlbumGeneric = 200,

PHAssetCollectionSubtypeSmartAlbumPanoramas = 201, // 全景圖、全景照片

PHAssetCollectionSubtypeSmartAlbumVideos = 202, // 視頻

PHAssetCollectionSubtypeSmartAlbumFavorites = 203, // 標記為喜歡、收藏

PHAssetCollectionSubtypeSmartAlbumTimelapses = 204, // 延時拍攝、定時拍攝

PHAssetCollectionSubtypeSmartAlbumAllHidden = 205, // 隱藏的

PHAssetCollectionSubtypeSmartAlbumRecentlyAdded = 206,

PHAssetCollectionSubtypeSmartAlbumBursts = 207, // 連拍

PHAssetCollectionSubtypeSmartAlbumSlomoVideos = 208,

PHAssetCollectionSubtypeSmartAlbumUserLibrary = 209, // 相機膠卷

PHAssetCollectionSubtypeSmartAlbumSelfPortraits PHOTOS_AVAILABLE_IOS_TVOS(9_0, 10_0) = 210, // 使用前置錄影頭拍攝的作品

PHAssetCollectionSubtypeSmartAlbumScreenshots PHOTOS_AVAILABLE_IOS_TVOS(9_0, 10_0) = 211, // 螢幕截圖

PHAssetCollectionSubtypeSmartAlbumDepthEffect PHOTOS_AVAILABLE_IOS_TVOS(10_2, 10_1) = 212,

PHAssetCollectionSubtypeSmartAlbumLivePhotos PHOTOS_AVAILABLE_IOS_TVOS(10_3, 10_2) = 213, // Live Photo資源

PHAssetCollectionSubtypeSmartAlbumAnimated PHOTOS_AVAILABLE_IOS_TVOS(11_0, 11_0) = 214,

PHAssetCollectionSubtypeSmartAlbumLongExposures PHOTOS_AVAILABLE_IOS_TVOS(11_0, 11_0) = 215,

// Used for fetching, if you don’t care about the exact subtype

PHAssetCollectionSubtypeAny = NSIntegerMax

} PHOTOS_ENUM_AVAILABLE_IOS_TVOS( 8_0, 10_0);

ok,趕快舉個獲取全部相片例子:

// 獲得相機膠卷

PHFetchResult *cameraRolls = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options: nil];

// cameraRolls:將來我們就用它來獲取相冊的圖片

不要慌,看這個參數感覺頭大不要緊,一會看到demo的時候,簡單的一批。

3.PHFetchResult

相冊管理的類,是有序的photo實體對象的容器,包含通過給定的檢索條件返回的asset,相冊,一個相冊類型中的所有相冊列表。你要是實在搞不懂我說的是什麼,你就把他想成NSMutableArray。(當然它和NSMutableArray只是用法上類似,他們之間沒什麼關係)

4.PHAsset

重頭戲來了哈,這個就是需要重點介紹的。這個類相當於一張照片的實體,我們可以通過處理變成可見的照片,而且還能獲取到照片的經緯度(前提是有經緯度)、創建時間,這對於產品來說是非常重要的參數。

我們就抽這個類幾個重要的屬性講一下,其他同學們可以自學一下:

/// 像素寬高

@property( nonatomic, assign, readonly) NSUIntegerpixelWidth;

@property( nonatomic, assign, readonly) NSUIntegerpixelHeight;

/// 創建時間、修改時間

@property( nonatomic, strong, readonly, nullable) NSDate*creationDate;

@property( nonatomic, strong, readonly, nullable) NSDate*modificationDate;

/// 經緯度

@property( nonatomic, strong, readonly, nullable) CLLocation*location;

/// 持續時間

@property( nonatomic, assign, readonly) NSTimeIntervalduration;

/// 通過PHAssetCollection獲取PHFetchResult *,獲取到PHAsset之後就可以得到圖片了

+ (PHFetchResult *)fetchAssetsInAssetCollection:(PHAssetCollection *)assetCollection options:( nullablePHFetchOptions *)options;

哇,看到這些爽不爽啊,獲取個圖片,這麼多相關屬性都出來了。

5. PHImageManager

按照要求獲取制定的圖片

/// 通過PHAsset,加上你需要展示的圖片大小、圖片類型(是否裁剪等)和PHImageRequestOptions去獲取圖片

– (PHImageRequestID)requestImageForAsset:(PHAsset *)asset targetSize:( CGSize)targetSize contentMode:(PHImageContentMode)contentMode options:( nullablePHImageRequestOptions *)options resultHandler:( void(^)( UIImage*__ nullableresult, NSDictionary*__ nullableinfo))resultHandler;

/// 這個就是調用的方法獲取圖片

[[PHImageManager defaultManager] requestImageForAsset: self.asset targetSize: CGSizeMake(imageWidth * [ UIScreenmainScreen].scale, imageWidth * [ UIScreenmainScreen].scale) contentMode:PHImageContentModeDefault options:options resultHandler:^( UIImage* _Nullable result, NSDictionary* _Nullable info) {

NSLog( @”獲取的圖片:%@”, result);

}];

6.PHImageRequestOptions

請求選項設置,這里也將它的重點屬性講解一下:

// resize mode. Does not apply when size is PHImageManagerMaximumSize. Defaults to PHImageRequestOptionsResizeModeNone (or no resize)

@property( nonatomic, assign) PHImageRequestOptionsResizeMode resizeMode;

// 自定義設置圖片的大小

typedefNS_ENUM( NSInteger, PHImageRequestOptionsResizeMode) {

PHImageRequestOptionsResizeModeNone = 0, // 保持原size(不調整大小)

PHImageRequestOptionsResizeModeFast, //高效、但不保證圖片的size為自定義size(由系統去安排,情況不定:有時你設置的size比較小,會根據你設的size,有時又會比大)

PHImageRequestOptionsResizeModeExact, // 嚴格按照自定義size

} PHOTOS_ENUM_AVAILABLE_IOS_TVOS( 8_0, 10_0);

// return only a single result, blocking until available (or failure). Defaults to NO

@property( nonatomic, assign, getter=isSynchronous) BOOLsynchronous;

// 指定請求是否同步執行。

// specify crop rectangle in unit coordinates of the original image, such as a face. Defaults to CGRectZero (not applicable)

@property( nonatomic, assign) CGRectnormalizedCropRect;

// 用於對原始尺寸的圖像進行裁剪,基於比例坐標。只在 resizeMode 為 Exact 時有效。

// delivery mode. Defaults to PHImageRequestOptionsDeliveryModeOpportunistic

@property( nonatomic, assign) PHImageRequestOptionsDeliveryMode deliveryMode;

// 圖像質量。有三種值:Opportunistic,在速度與質量中均衡;HighQualityFormat,不管花費多長時間,提供高質量圖像;FastFormat,以最快速度提供好的質量。 這個屬性只有在 synchronous 為 true 時有效。

ok,截止到目前,獲取相冊所有重要的類、參數、方法都講完了。我們來講講demo吧。

我覺得整個demo的方法沒有必要一條條的講解,主要是思路和防止一些坑。

首先我們在進入控制器的時候,獲取你需要顯示的相冊,再在主控制器顯示第一個相冊。

在加載圖片的時候,我建議大家將加載的方法放在cell中完成,但是要保證cell的重用問題,千萬不要把圖片解析到model中,小心撐炸APP。

可以做一個單例,用於記錄選中的圖片、選中的總數等等。

其實大家把方法搞明白之後,整個demo的邏輯其實很簡單。

demo的鏈接:

https://github.com/Fdevelopmenter/LYFAlbum

喜歡的同學點個讚哈

About 尋夢園
尋夢園是台灣最大的聊天室及交友社群網站。 致力於發展能夠讓會員們彼此互動、盡情分享自我的平台。 擁有數百間不同的聊天室 ,讓您隨時隨地都能找到志同道合的好友!