iOS 使用PHPickerViewController選擇圖片和視頻

iOS 14開始推出了PHPicker返奉,更加快了UIImagePickerController退出歷史舞臺的步伐现横,取而代之的是PHPickerViewController怀各,但PHPicker現(xiàn)在只能在iOS上使用听系,macOS舍悯、tvOS及watchOS下不可用航棱。PHPicker還是依賴PHPhotoLibrary,只是PHPickerViewController在處理代理結(jié)果回調(diào)上有所變化萌衬,返回的是新的類PHPickerResult饮醇,而不再是通過NSDictionary信息獲取PHAsset或UIImage對象。

另外PHPickerViewController只申明了一個代理事件奄薇,也就是說不管是選擇視頻驳阎、圖片,還是取消操作都是在同一個代理事件中進行處理馁蒂,而UIImagePickerController分別提供了圖片呵晚、視頻、取消三個代理事件沫屡,不同的操作需要實現(xiàn)不同的代理事件饵隙。

使用PHPickerViewController選擇圖片需要關鍵的兩個類:PHPickerConfiguration和PHPickerFilter。PHPickerConfiguration用來對PHPickerViewController進行相關配置沮脖,包括模式金矛、數(shù)量及過濾器(PHPickerFilter);PHPickerFilter用于設置所過濾的文件類型勺届,包括圖片驶俊、視頻及現(xiàn)場圖片(LivePhoto)。

初始化

//為了不影響14以下系統(tǒng)功能免姿,需要做向下兼容

? ? if(@available(iOS14, *)) {

? ? ? ? //初始化過濾器(PHPickerFilter)

? ? ? ? PHPickerFilter *filter = [PHPickerFilter anyFilterMatchingSubfilters:@[PHPickerFilter.videosFilter]];//過濾器提供三種類型的過濾imagesFilter饼酿、videosFilter和livePhotosFilter

? ? ? ? //初始化PHPickerConfiguration對象(信息配置)

? ? ? ? PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];

? ? ? ? //設置過濾器,默認為nil胚膊,表示選擇所有類型的文件

? ? ? ? config.filter= filter;

? ? ? ? //設置模式包括Automatic故俐、Current和Compatible(分別代表最佳、當前紊婉、最兼容)药版,默認為Automatic

? ? ? ? config.preferredAssetRepresentationMode = PHPickerConfigurationAssetRepresentationModeCurrent;

? ? ? ? //設置選擇最大數(shù)量,默認為1喻犁,0表示系統(tǒng)最大數(shù)量值

? ? ? ? config.selectionLimit=1;

? ? ? ? //初始化圖片選擇控制器

? ? ? ? PHPickerViewController *pickerVC = [[PHPickerViewController alloc] initWithConfiguration:config];

? ? ? ? //設置選擇控制器代理

? ? ? ? pickerVC.delegate=self;

? ? ? ? //展示

? ? ? ? [self presentViewController:pickerVC animated:YES completion:nil];

? ? }else{

? ? ? ? // Fallback on earlier versions

? ? ? ? // You can use UIImagePickerController to do something here.

? ? }

實現(xiàn)PHPickerViewControllerDelegate代理方法

實現(xiàn)代理方法

#pragma mark - PHPickerViewControllerDelegate

- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult*> *)results? API_AVAILABLE(ios(14)){

? ? [picker dismissViewControllerAnimated:YES completion:nil];

? ? if(!results || !results.count) {

? ? ? ? //點擊了取消

? ? }else{

? ? ? ? //這里演示一張圖片的

? ? ? ? //取出PHPickerResult對象,PHPickerResult類公開itemProvider和assetIdentifier屬性槽片,其中itemProvider用來獲取資源文件的數(shù)據(jù)或?qū)ο蠛位海琣ssetIdentifier文檔里只做了屬性說明就是文件的一個本地唯一ID,蘋果官方操作指南也沒有提到這個屬性用法筐乳,只是對assetIdentifier做了一下簡單的本地緩存和過濾操作(是否選擇同一個文件)

? ? ? ? PHPickerResult *result = [resultsfirstObject];

? ? ? ? //定義NSItemProvider對象

? ? ? ? NSItemProvider *itemProvoider = result.itemProvider;

? ? ? ? //根據(jù)判斷并加載文件

? ? ? ? if ([itemProvoider canLoadObjectOfClass:[PHLivePhoto class]]) {

? ? ? ? ? ? //或者[result.itemProvider canLoadObjectOfClass:[UIImage class]]

? ? ? ? ? ? [itemProvoider loadObjectOfClass:[PHLivePhoto class] completionHandler:^(__kindof id<NSItemProviderReading>? _Nullable object, NSError * _Nullable error) {

? ? ? ? ? ? ? ? //返回的object屬于PHLivePhoto對象歌殃,如果load的類是UIImage這里的object返回UIImage類

? ? ? ? ? ? ? ? //處理PHLivePhoto對象

? ? ? ? ? ? ? ? PHLivePhoto *lpObj = (PHLivePhoto*)object;

? ? ? ? ? ? ? ? NSURL *url = [lpObj valueForKey:@"imageURL"];//圖片本地URL

? ? ? ? ? ? ? ? UIImage *image = [UIImage imageWithContentsOfFile:[url path]];//得到的圖片UIImage對象

? ? ? ? ? ? ? ? //或者[NSData dataWithContentsOfFile:[url path]]轉(zhuǎn)NSData數(shù)據(jù)

? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? self.resultImg.image = image;

? ? ? ? ? ? ? ? });

? ? ? ? ? ? }];

? ? ? ? }else{

? ? ? ? ? ? //圖片

? ? ? ? ? ? if ([itemProvoider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {

? ? ? ? ? ? ? ? [itemProvoider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(__kindof id<NSSecureCoding>? _Nullable item, NSError * _Null_unspecified error) {

? ? ? ? ? ? ? ? ? ? if([item isKindOfClass:[NSURL class]]) {

? ? ? ? ? ? ? ? ? ? ? ? NSURL*url = (NSURL*)item;//圖片本地URL

? ? ? ? ? ? ? ? ? ? ? ? UIImage *image = [UIImage imageWithContentsOfFile:[url path]];//得到的圖片UIImage對象

? ? ? ? ? ? ? ? ? ? ? ? //或者[NSData dataWithContentsOfFile:[url path]]轉(zhuǎn)NSData數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? ? ? ? ? self.resultImg.image = image;

? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }];

? ? ? ? ? ? }

? ? ? ? ? ? //這里演示一個視頻

? ? ? ? ? ? if ([itemProvoider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeVideo]) {

? ? ? ? ? ? ? ? [itemProvoider loadItemForTypeIdentifier:(NSString *)kUTTypeVideo options:nil completionHandler:^(__kindof id<NSSecureCoding>? _Nullable item, NSError * _Null_unspecified error) {

? ? ? ? ? ? ? ? ? ? NSURL*url = (NSURL*)item;//視頻本地URL

? ? ? ? ? ? ? ? ? ? NSData *data = [NSData dataWithContentsOfURL:url];//視頻數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? //獲取視頻截圖

? ? ? ? ? ? ? ? ? ? AVURLAsset *urlAsset = [AVURLAsset assetWithURL:url];

? ? ? ? ? ? ? ? ? ? AVAssetImageGenerator *imgGen = [[AVAssetImageGenerator alloc] initWithAsset:urlAsset];

? ? ? ? ? ? ? ? ? ? //設定縮略圖的方向,如果不設定蝙云,獲取到的縮略圖可能是被旋轉(zhuǎn)過的氓皱,而不是正向的。

? ? ? ? ? ? ? ? ? ? imgGen.appliesPreferredTrackTransform=YES;

? ? ? ? ? ? ? ? ? ? //取第一秒的截圖

? ? ? ? ? ? ? ? ? ? CMTimecT =CMTimeMake(1, urlAsset.duration.timescale);

? ? ? ? ? ? ? ? ? ? CMTime aT;NSError *err;

? ? ? ? ? ? ? ? ? ? CGImageRef cgImg = [imgGen copyCGImageAtTime:cT actualTime:&aT error:&err];

? ? ? ? ? ? ? ? ? ? UIImage *resultImg = [UIImage imageWithCGImage:cgImg];

? ? ? ? ? ? ? ? ? ? if(resultImg) {

? ? ? ? ? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(), ^{

? ? ? ? ? ? ? ? ? ? ? ? ? ? self.resultImg.image = resultImg;//展示截圖

? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? ? ? NSLog(@"截圖失敗");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? self.videoData= data;//緩存視頻數(shù)據(jù)

? ? ? ? ? ? ? ? }];

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

在處理PHPickerViewControllerDelegate代理事件中勃刨,上述代碼中出現(xiàn)的“kUTTypeImage”以及“kUTTypeVideo”波材,可以使用另一種方式去代替。NSItemProvider提供了一個數(shù)組類型屬性registeredTypeIdentifiers身隐,數(shù)組里存放TypeIdentifier廷区,從而可以從數(shù)組取值替換掉“kUTTypeImage”和“kUTTypeVideo”:[itemProvoider.registeredTypeIdentifiers firstObject]替換“kUTTypeImage”

registeredTypeIdentifiers數(shù)組

如果在編譯時報錯:Use of undeclared identifier 'kUTTypeVideo’或者’kUTTypeImage’,那是因為沒有導入MobileCoreServices或者CoreServices框架

解決步驟如下:TARGETS->Build Phases->Link Binary With Libraries,添加MobileCoreServices.framework或者CoreServices.framework贾铝,在需要用到的地方引入頭文件#import?<MobileCoreServices/MobileCoreServices.h>/#import?<CoreServices/CoreServices.h>

鏈入框架
引入頭文件

運行看效果

效果

結(jié)尾附上官方鏈接Selecting Photos and Videos in iOS

以上所述如有錯誤隙轻,歡迎指教??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市垢揩,隨后出現(xiàn)的幾起案子玖绿,更是在濱河造成了極大的恐慌,老刑警劉巖叁巨,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斑匪,死亡現(xiàn)場離奇詭異,居然都是意外死亡锋勺,警方通過查閱死者的電腦和手機蚀瘸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庶橱,“玉大人贮勃,你說我怎么就攤上這事∷照拢” “怎么了衙猪?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長布近。 經(jīng)常有香客問我,道長丝格,這世上最難降的妖魔是什么撑瞧? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮显蝌,結(jié)果婚禮上预伺,老公的妹妹穿的比我還像新娘订咸。我一直安慰自己,他們只是感情好酬诀,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布脏嚷。 她就那樣靜靜地躺著,像睡著了一般瞒御。 火紅的嫁衣襯著肌膚如雪父叙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天肴裙,我揣著相機與錄音趾唱,去河邊找鬼。 笑死蜻懦,一個胖子當著我的面吹牛甜癞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宛乃,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼悠咱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了征炼?” 一聲冷哼從身側(cè)響起析既,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柒室,沒想到半個月后渡贾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡雄右,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年空骚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片擂仍。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡囤屹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逢渔,到底是詐尸還是另有隱情肋坚,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布肃廓,位于F島的核電站智厌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盲赊。R本人自食惡果不足惜铣鹏,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哀蘑。 院中可真熱鬧诚卸,春花似錦葵第、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至棠赛,卻和暖如春哮奇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恭朗。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工屏镊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痰腮。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓而芥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親膀值。 傳聞我的和親對象是個殘疾皇子棍丐,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容