如何优雅地使用iOS系统相机、相册

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看160 回复回复6 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 160|回复: 6
收起左侧

如何优雅地使用iOS系统相机、相册

[复制链接]
蚊香酱 发表于 2016-8-19 18:52:36 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑

如何优雅地使用iOS系统相机、相册

如何优雅地使用iOS系统相机、相册 - 敏捷大拇指 - 如何优雅地使用iOS系统相机、相册



# 如何优雅地使用iOS系统相机、相册
### 概述

iOS系统相机、相册功能全部依托于图像选取控制器UIImagePickerController,在使用该控制器时,我们需要按照如下步骤进行

1. 检查指定的资源类型是否可用
2. 检查指定资源类型下是否支持指定的媒体类型
3. 检查用户对相机、相册的授权状态
4. 初始化并弹出图像选取控制器
5. 处理操作完成后的代理回调

### 检查指定的资源类型是否可用

这步操作用于检查设备是否支持指定的资源类型,以防盲目调用图像选取器导致程序不可用,比如采用模拟器调用相机

图像选取控制器的资源类型是一个枚举,拥有如下三种类型

```objc
UIImagePickerControllerSourceTypeCamera // 相机类型
UIImagePickerControllerSourceTypePhotoLibrary // 照片库类型,相当于系统应用"照片"中的"相簿/Photos"栏加上"照片/Moments"栏
UIImagePickerControllerSourceTypeSavedPhotosAlbum // 照片类型,相当于系统应用"照片"中的"照片/Moments"栏
```

我们可以使用isSourceTypeAvailable方法进行检查

```objc
// 以"检查图像选择器的相机类型是否可用"为例

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
  // 相机类型可用
}
else
{
  // 相机类型不可用
}
```

### 检查指定资源类型下是否支持指定的媒体类型

这步操作用于检查某种资源类型下是否支持某种媒体类型,比如iPhone是否可以拍LivePhoto

图像选取控制器的媒体类型主要分为两大类,图片类型与视频类型

```objc
kUTTypeImage(图片类型,细分为kUTTypeJPEG、kUTTypeGIF、kUTTypeLivePhoto等)
kUTTypeMovie(视频类型,细分为kUTTypeMovie、kUTTypeMP3、kUTTypeAVIMovie等)
```

> 注1: 媒体类型以常量形式定义,需要引入MobileCoreServices.framework

> 注2: 媒体类型常量是CFString类型,在使用时需要强转为NSString类型

我们可以使用availableMediaTypesForSourceType:方法返回指定资源类型下支持的媒体类型数组

```objc
// 以"检查图像选择器在相机类型下是否支持图片类型"为例

// 返回相机类型下支持的媒体类型数组
NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
// 判断数组中是否拥有(NSString *)kUTTypeImage元素
if ([availableMediaTypes containsObjectNSString *)kUTTypeImage])
{
  // 图片类型可用
}
else
{
  // 图片类型不可用
}
```

### 检查用户对相机、相册的授权状态

这步操作根据用户授权状态决定是否弹出图像选取控制器,比如用户授权状态为拒绝状态,那么便需要提示用户,而不是弹出一个黑屏的控制器

##### 检查用户对相机的授权状态

> 注: 需要引入AVFoundation.framework

相机媒体类型主要有两种常用类型

```objc
AVMediaTypeVideo(视频媒体类型)
AVMediaTypeAudio(音频媒体类型)
```

用户对相机的授权状态是一个枚举,拥有如下四种类型

```objc
AVAuthorizationStatusNotDetermined // 用户没有选择是否授权使用
AVAuthorizationStatusRestricted // 用户禁止使用,且授权状态不可修改,可能由于家长控制功能
AVAuthorizationStatusDenied // 用户已经禁止使用
AVAuthorizationStatusAuthorized // 用户已经授权使用
```

我们可以使用authorizationStatusForMediaType:方法返回用户对指定的相机媒体类型的授权状态

```objc
// 以"检查用户对视频媒体类型的授权状态"为例

// 返回用户对视频媒体类型的授权状态
AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
// 处理不同授权状态下的操作流程
switch (authorizationStatus)
{
  case AVAuthorizationStatusNotDetermined:
  {
    // 用户没有选择是否授权使用
  }
  break;
case AVAuthorizationStatusRestricted:
  {
    // 用户禁止使用,且授权状态不可修改,可能由于家长控制功能
  }
  break;
  case AVAuthorizationStatusDenied:
  {
    // 用户已经禁止使用
  }
  break;
  case AVAuthorizationStatusAuthorized:
  {
    // 用户已经授权使用
  }
  break;
}
```

在相机授权状态为AVAuthorizationStatusNotDetermined时,我们有必要先利用requestAccessForMediaType:completionHandler:方法来弹窗要求用户选择是否授权,而非直接弹出图像选取控制器,由系统自动弹窗询问用户是否授权

```objc
// 以"弹窗要求用户选择是否授权"为例

[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
    if(granted)
    {
        // 用户授权使用
    }
    else
    {
        // 用户禁止使用
    }
}];
```

> 注1: 该弹窗只在授权状态为AVAuthorizationStatusNotDetermined时才会显示

> 注2: 在使用AVCaptureDeviceInput且授权状态为AVAuthorizationStatusNotDetermined时,该弹窗会自动显示

##### 检查用户对相册的授权状态

> 注: 需要引入AssetsLibrary.framework

用户对相册的授权状态是一个枚举,拥有如下四种类型

```objc
ALAuthorizationStatusNotDetermined // 用户没有选择是否授权使用
ALAuthorizationStatusRestricted // 用户禁止使用,且授权状态不可修改,可能由于家长控制功能
ALAuthorizationStatusDenied // 用户已经禁止使用
ALAuthorizationStatusAuthorized // 用户已经授权使用
```

我们可以使用authorizationStatus方法返回用户对相册的授权状态

```objc
// 以"检查用户对相册的授权状态"为例

// 返回用户对相册的授权状态
ALAuthorizationStatus authorizationStatus = [ALAssetsLibrary authorizationStatus];
// 处理不同授权状态下的操作流程
switch (authorizationStatus)
{
  case ALAuthorizationStatusNotDetermined:
  {
    // 用户没有选择是否授权使用
  }
  break;
  case ALAuthorizationStatusRestricted:
  {
    // 用户禁止使用,且授权状态不可修改,可能由于家长控制功能
  }
  break;
  case ALAuthorizationStatusDenied:
  {
    // 用户已经禁止使用
  }
  break;
  case ALAuthorizationStatusAuthorized:
  {
    // 用户已经授权使用
  }
  break;
}
```

### 初始化并弹出图像选取控制器
##### 初始化相机控制器

```objc
// 创建图像选取控制器对象
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// 将资源类型设置为相机类型
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
// 将媒体类型设置为图片类型和视频类型(数组中如果只写一个,图像选择控制器即只允许拍照/录像)
picker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
// 设置拍照后的图片允许编辑
picker.allowsEditing = YES;
// 设置摄像图像品质,默认是UIImagePickerControllerQualityTypeMedium
picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
// 设置最长摄像时间,默认是10秒
picker.videoMaximumDuration = 30;
// 设置代理,需要遵守<UINavigationControllerDelegate, UIImagePickerControllerDelegate>两个协议
picker.delegate = self;
// 弹出图像选取控制器
[self presentViewController:picker animated:YES completion:nil];
```

##### 初始化相册控制器

```objc
// 创建图像选取控制器对象
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
// 将资源类型设置为相册类型
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// 将媒体类型设置为图片类型和视频类型(数组中如果只写一个,图像选择控制器即只能选取图片/视频)
picker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
// 设置选取后的图片允许编辑
picker.allowsEditing = YES;
// 设置代理,需要遵守<UINavigationControllerDelegate, UIImagePickerControllerDelegate>两个协议
picker.delegate = self;
// 弹出图像选取控制器
[self presentViewController:picker animated:YES completion:nil];
```

### 处理操作完成后的代理回调

在对相机、相册操作完成后,系统会回调如下两个代理方法

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

  // 回收图像选取控制器
  [picker dismissViewControllerAnimated:YES completion:nil];
}

// 操作取消
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
  // 回收图像选取控制器
  [picker dismissViewControllerAnimated:YES completion:nil];
}
```

在操作完成回调info字典中,拥有如下可用信息

```objc
UIImagePickerControllerMediaType // 媒体类型(kUTTypeImage、kUTTypeMovie等)
UIImagePickerControllerOriginalImage // 原始图片
UIImagePickerControllerEditedImage // 编辑后图片
UIImagePickerControllerCropRect // 裁剪尺寸
UIImagePickerControllerMediaMetadata // 拍照的元数据
UIImagePickerControllerMediaURL // 媒体的URL
UIImagePickerControllerReferenceURL // 引用相册的URL
UIImagePickerControllerLivePhoto // PHLivePhoto
```

### 小提示
Q: 在使用系统相机、相册时,发现系统语言都是英文,比如"取消"显示为"Cancel",如何才能调整为中文

A: 这里有两种处理方式

- 方法一(不推荐): 在info.plist文件中有一个Localization native development region,默认为en,修改为China即可,这样默认语言即为中文
- 方法二(推荐): 在info.plist文件中有一个Localized resources can be mixed,默认为NO,修改为YES即可,这样会随着系统语言变化


都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

美人虞 发表于 2016-8-19 19:45:42 | 显示全部楼层
厉害!
大秘小蜜 发表于 2016-8-20 17:52:09 | 显示全部楼层
手动点赞!
买定离手 发表于 2016-8-22 12:16:52 | 显示全部楼层
能不能用中文逗号句号啊
 楼主| 蚊香酱 发表于 2016-8-22 14:33:49 | 显示全部楼层
买定离手 发表于 2016-8-22 12:16
能不能用中文逗号句号啊

已经习惯了
linus 发表于 2016-8-28 11:54:01 | 显示全部楼层

每次看楼主的帖子,都要花至少半小时……
数学家 发表于 2016-9-5 18:17:38 | 显示全部楼层
楼主能改成Swift3.0版本不~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
关闭

站长推荐 上一条 /3 下一条

热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表