如何優(yōu)雅地使用iOS系統(tǒng)相機(jī)、相冊(cè)

cameraphoto.png

概述

iOS系統(tǒng)相機(jī)、相冊(cè)功能全部依托于圖像選取控制器UIImagePickerController,在使用該控制器時(shí),我們需要按照如下步驟進(jìn)行

  1. 檢查指定的資源類(lèi)型是否可用
  2. 檢查指定資源類(lèi)型下是否支持指定的媒體類(lèi)型
  3. 檢查用戶(hù)對(duì)相機(jī)、相冊(cè)的授權(quán)狀態(tài)
  4. 初始化并彈出圖像選取控制器
  5. 處理操作完成后的代理回調(diào)

檢查指定的資源類(lèi)型是否可用

這步操作用于檢查設(shè)備是否支持指定的資源類(lèi)型,以防盲目調(diào)用圖像選取器導(dǎo)致程序不可用,比如采用模擬器調(diào)用相機(jī)

圖像選取控制器的資源類(lèi)型是一個(gè)枚舉,擁有如下三種類(lèi)型

UIImagePickerControllerSourceTypeCamera // 相機(jī)類(lèi)型
UIImagePickerControllerSourceTypePhotoLibrary // 照片庫(kù)類(lèi)型,相當(dāng)于系統(tǒng)應(yīng)用"照片"中的"相簿/Photos"欄加上"照片/Moments"欄
UIImagePickerControllerSourceTypeSavedPhotosAlbum // 照片類(lèi)型,相當(dāng)于系統(tǒng)應(yīng)用"照片"中的"照片/Moments"欄

我們可以使用isSourceTypeAvailable方法進(jìn)行檢查

// 以"檢查圖像選擇器的相機(jī)類(lèi)型是否可用"為例

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
  // 相機(jī)類(lèi)型可用
}
else
{
  // 相機(jī)類(lèi)型不可用
}

檢查指定資源類(lèi)型下是否支持指定的媒體類(lèi)型

這步操作用于檢查某種資源類(lèi)型下是否支持某種媒體類(lèi)型,比如iPhone是否可以拍LivePhoto

圖像選取控制器的媒體類(lèi)型主要分為兩大類(lèi),圖片類(lèi)型與視頻類(lèi)型

kUTTypeImage(圖片類(lèi)型,細(xì)分為kUTTypeJPEG、kUTTypeGIF、kUTTypeLivePhoto等)
kUTTypeMovie(視頻類(lèi)型,細(xì)分為kUTTypeMovie、kUTTypeMP3、kUTTypeAVIMovie等)

注1: 媒體類(lèi)型以常量形式定義,需要引入MobileCoreServices.framework

注2: 媒體類(lèi)型常量是CFString類(lèi)型,在使用時(shí)需要強(qiáng)轉(zhuǎn)為NSString類(lèi)型

我們可以使用availableMediaTypesForSourceType:方法返回指定資源類(lèi)型下支持的媒體類(lèi)型數(shù)組

// 以"檢查圖像選擇器在相機(jī)類(lèi)型下是否支持圖片類(lèi)型"為例

// 返回相機(jī)類(lèi)型下支持的媒體類(lèi)型數(shù)組
NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
// 判斷數(shù)組中是否擁有(NSString *)kUTTypeImage元素
if ([availableMediaTypes containsObject:(NSString *)kUTTypeImage])
{
  // 圖片類(lèi)型可用
}
else
{
  // 圖片類(lèi)型不可用
}

檢查用戶(hù)對(duì)相機(jī)、相冊(cè)的授權(quán)狀態(tài)

這步操作根據(jù)用戶(hù)授權(quán)狀態(tài)決定是否彈出圖像選取控制器,比如用戶(hù)授權(quán)狀態(tài)為拒絕狀態(tài),那么便需要提示用戶(hù),而不是彈出一個(gè)黑屏的控制器

檢查用戶(hù)對(duì)相機(jī)的授權(quán)狀態(tài)

注: 需要引入AVFoundation.framework

相機(jī)媒體類(lèi)型主要有兩種常用類(lèi)型

AVMediaTypeVideo(視頻媒體類(lèi)型)
AVMediaTypeAudio(音頻媒體類(lèi)型)

用戶(hù)對(duì)相機(jī)的授權(quán)狀態(tài)是一個(gè)枚舉,擁有如下四種類(lèi)型

AVAuthorizationStatusNotDetermined // 用戶(hù)沒(méi)有選擇是否授權(quán)使用
AVAuthorizationStatusRestricted // 用戶(hù)禁止使用,且授權(quán)狀態(tài)不可修改,可能由于家長(zhǎng)控制功能
AVAuthorizationStatusDenied // 用戶(hù)已經(jīng)禁止使用
AVAuthorizationStatusAuthorized // 用戶(hù)已經(jīng)授權(quán)使用

我們可以使用authorizationStatusForMediaType:方法返回用戶(hù)對(duì)指定的相機(jī)媒體類(lèi)型的授權(quán)狀態(tài)

// 以"檢查用戶(hù)對(duì)視頻媒體類(lèi)型的授權(quán)狀態(tài)"為例

// 返回用戶(hù)對(duì)視頻媒體類(lèi)型的授權(quán)狀態(tài)
AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
// 處理不同授權(quán)狀態(tài)下的操作流程
switch (authorizationStatus)
{
  case AVAuthorizationStatusNotDetermined:
  {
    // 用戶(hù)沒(méi)有選擇是否授權(quán)使用
  }
  break;
case AVAuthorizationStatusRestricted:
  {
    // 用戶(hù)禁止使用,且授權(quán)狀態(tài)不可修改,可能由于家長(zhǎng)控制功能
  }
  break;
  case AVAuthorizationStatusDenied:
  {
    // 用戶(hù)已經(jīng)禁止使用
  }
  break;
  case AVAuthorizationStatusAuthorized:
  {
    // 用戶(hù)已經(jīng)授權(quán)使用
  }
  break;
}

在相機(jī)授權(quán)狀態(tài)為AVAuthorizationStatusNotDetermined時(shí),我們有必要先利用requestAccessForMediaType:completionHandler:方法來(lái)彈窗要求用戶(hù)選擇是否授權(quán),而非直接彈出圖像選取控制器,由系統(tǒng)自動(dòng)彈窗詢(xún)問(wèn)用戶(hù)是否授權(quán)

// 以"彈窗要求用戶(hù)選擇是否授權(quán)"為例

[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
    if(granted)
    {
        // 用戶(hù)授權(quán)使用
    }
    else
    {
        // 用戶(hù)禁止使用
    }
}];

注1: 該彈窗只在授權(quán)狀態(tài)為AVAuthorizationStatusNotDetermined時(shí)才會(huì)顯示

注2: 在使用AVCaptureDeviceInput且授權(quán)狀態(tài)為AVAuthorizationStatusNotDetermined時(shí),該彈窗會(huì)自動(dòng)顯示

檢查用戶(hù)對(duì)相冊(cè)的授權(quán)狀態(tài)

注: 需要引入AssetsLibrary.framework

用戶(hù)對(duì)相冊(cè)的授權(quán)狀態(tài)是一個(gè)枚舉,擁有如下四種類(lèi)型

ALAuthorizationStatusNotDetermined // 用戶(hù)沒(méi)有選擇是否授權(quán)使用
ALAuthorizationStatusRestricted // 用戶(hù)禁止使用,且授權(quán)狀態(tài)不可修改,可能由于家長(zhǎng)控制功能
ALAuthorizationStatusDenied // 用戶(hù)已經(jīng)禁止使用
ALAuthorizationStatusAuthorized // 用戶(hù)已經(jīng)授權(quán)使用

我們可以使用authorizationStatus方法返回用戶(hù)對(duì)相冊(cè)的授權(quán)狀態(tài)

// 以"檢查用戶(hù)對(duì)相冊(cè)的授權(quán)狀態(tài)"為例

// 返回用戶(hù)對(duì)相冊(cè)的授權(quán)狀態(tài)
ALAuthorizationStatus authorizationStatus = [ALAssetsLibrary authorizationStatus];
// 處理不同授權(quán)狀態(tài)下的操作流程
switch (authorizationStatus)
{
  case ALAuthorizationStatusNotDetermined:
  {
    // 用戶(hù)沒(méi)有選擇是否授權(quán)使用
  }
  break;
  case ALAuthorizationStatusRestricted:
  {
    // 用戶(hù)禁止使用,且授權(quán)狀態(tài)不可修改,可能由于家長(zhǎng)控制功能
  }
  break;
  case ALAuthorizationStatusDenied:
  {
    // 用戶(hù)已經(jīng)禁止使用
  }
  break;
  case ALAuthorizationStatusAuthorized:
  {
    // 用戶(hù)已經(jīng)授權(quán)使用
  }
  break;
}

初始化并彈出圖像選取控制器

初始化相機(jī)控制器
// 創(chuàng)建圖像選取控制器對(duì)象
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// 將資源類(lèi)型設(shè)置為相機(jī)類(lèi)型
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// 將媒體類(lèi)型設(shè)置為圖片類(lèi)型和視頻類(lèi)型(數(shù)組中如果只寫(xiě)一個(gè),圖像選擇控制器即只允許拍照/錄像)
picker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
// 設(shè)置拍照后的圖片允許編輯
picker.allowsEditing = YES;
// 設(shè)置攝像圖像品質(zhì),默認(rèn)是UIImagePickerControllerQualityTypeMedium
picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
// 設(shè)置最長(zhǎng)攝像時(shí)間,默認(rèn)是10秒
picker.videoMaximumDuration = 30;
// 設(shè)置代理,需要遵守<UINavigationControllerDelegate, UIImagePickerControllerDelegate>兩個(gè)協(xié)議
picker.delegate = self;
// 彈出圖像選取控制器
[self presentViewController:picker animated:YES completion:nil];
初始化相冊(cè)控制器
// 創(chuàng)建圖像選取控制器對(duì)象
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// 將資源類(lèi)型設(shè)置為相冊(cè)類(lèi)型
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// 將媒體類(lèi)型設(shè)置為圖片類(lèi)型和視頻類(lèi)型(數(shù)組中如果只寫(xiě)一個(gè),圖像選擇控制器即只能選取圖片/視頻)
picker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
// 設(shè)置選取后的圖片允許編輯
picker.allowsEditing = YES;
// 設(shè)置代理,需要遵守<UINavigationControllerDelegate, UIImagePickerControllerDelegate>兩個(gè)協(xié)議
picker.delegate = self;
// 彈出圖像選取控制器
[self presentViewController:picker animated:YES completion:nil];

處理操作完成后的代理回調(diào)

在對(duì)相機(jī)、相冊(cè)操作完成后,系統(tǒng)會(huì)回調(diào)如下兩個(gè)代理方法

// 操作完成
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
  // do something ...

  // 回收?qǐng)D像選取控制器
  [picker dismissViewControllerAnimated:YES completion:nil];
}

// 操作取消
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
  // 回收?qǐng)D像選取控制器
  [picker dismissViewControllerAnimated:YES completion:nil];
}

在操作完成回調(diào)info字典中,擁有如下可用信息

UIImagePickerControllerMediaType // 媒體類(lèi)型(kUTTypeImage、kUTTypeMovie等)
UIImagePickerControllerOriginalImage // 原始圖片
UIImagePickerControllerEditedImage // 編輯后圖片
UIImagePickerControllerCropRect // 裁剪尺寸
UIImagePickerControllerMediaMetadata // 拍照的元數(shù)據(jù)
UIImagePickerControllerMediaURL // 媒體的URL
UIImagePickerControllerReferenceURL // 引用相冊(cè)的URL
UIImagePickerControllerLivePhoto // PHLivePhoto

小提示

Q: 在使用系統(tǒng)相機(jī)、相冊(cè)時(shí),發(fā)現(xiàn)系統(tǒng)語(yǔ)言都是英文,比如"取消"顯示為"Cancel",如何才能調(diào)整為中文

A: 這里有兩種處理方式

  • 方法一(不推薦): 在info.plist文件中有一個(gè)Localization native development region,默認(rèn)為en,修改為China即可,這樣默認(rèn)語(yǔ)言即為中文
  • 方法二(推薦): 在info.plist文件中有一個(gè)Localized resources can be mixed,默認(rèn)為NO,修改為YES即可,這樣會(huì)隨著系統(tǒng)語(yǔ)言變化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評(píng)論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,654評(píng)論 4 61
  • 我對(duì)這個(gè)世界沒(méi)什么留戀生無(wú)可戀有點(diǎn)可憐
    攝影師柳丁閱讀 187評(píng)論 0 1
  • 月光下,姑娘翩翩起舞 花姿亂顫 花開(kāi)了,蟲(chóng)子叫 飲罷一壺濁酒 意亂情迷 今夜沒(méi)人笑她癡話她醉 月光醉 醉成了空白 ...
    跟住閱讀 387評(píng)論 13 1

友情鏈接更多精彩內(nèi)容