基于 UIImagePickerController 的拓展封装 - iOS
基于 UIImagePickerController 的拓展,分别支持调用相机、相册的功能,其中相机可以设置默认调用前后摄像头;
简单对此进行了封装和实现,其中还有很多点可以继续挖掘和优化,该版本具体 code 如下:
声明:
/*
相机管理
*/ #import <Foundation/Foundation.h> @protocol YHCameraManagerDelegate <NSObject> /** 事件回调*/
- (void)YHCameraCallBack:(UIImage *)image; @end @interface YHCameraManager : NSObject @property (nonatomic, assign) id <YHCameraManagerDelegate> delegate; /** 单例对象*/
+ (instancetype)shareInstance; /**
调用相机或相册 @param deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller 当前 VC 控件
*/
- (void)openCameraOrPhotoLibraryWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller; /**
调用相机拍照 @param deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller 当前 VC 控件
*/
- (void)openCameraWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller; /**
调用相机拍摄
@param deviceType deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller controller 当前 VC 控件
*/
- (void)openCameraVideoWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller; /**
调用相册
@param controller 当前 VC 控件
*/
- (void)openPhotoLibraryWithController:(UIViewController *)controller; @end
实现:
#import "YHCameraManager.h"
#import <AssetsLibrary/AssetsLibrary.h>// 资源库 @interface YHCameraManager () <UIImagePickerControllerDelegate,UINavigationControllerDelegate> @end @implementation YHCameraManager #pragma mark - ****************************** Base
+ (instancetype)shareInstance {
static YHCameraManager *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[YHCameraManager alloc] init];
}); return singleton;
} #pragma mark - ****************************** Interface methods
/**
调用相机或相册(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param deviceType 摄像头设备类型
@param controller 当前 VC 控件
*/
- (void)openCameraOrPhotoLibraryWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller {
UIAlertController *alertCon = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet]; kWeakSelf(self);
[alertCon addAction:[UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [weakself openCameraWithCameraDeviceType:deviceType AndController:controller]; }]];
[alertCon addAction:[UIAlertAction actionWithTitle:@"从相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[weakself openPhotoLibraryWithController:controller]; }]]; [alertCon addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]]; [controller presentViewController:alertCon animated:YES completion:^{ }];
} /**
调用相机拍照(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param deviceType 摄像头设备类型
@param controller 当前 VC 控件
*/
- (void)openCameraWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller {
// 判断是否可以打开照相机
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController *pickerCon = [[UIImagePickerController alloc] init];
pickerCon.delegate = self;
pickerCon.allowsEditing = YES;// 设置拍摄的照片是否允许编辑 // 摄像头
pickerCon.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerCon.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;// 设置拍照类型(拍照 & 摄像)
if ([deviceType isEqualToString:@"Front"]) {// 设置使用手机摄像头类型
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceFront;// 设置使用手机前置摄像头
}
else {
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceRear;// 设置使用手机后置摄像头
} [controller presentViewController:pickerCon animated:YES completion:^{
NSLog(@"调用了 --- 摄像头");
}];
}
else {
[MBProgressHUD showCommonHudWithAlertString:@"没有摄像头" afterDelay:2.0 toView:controller.view];
}
} /**
调用相机拍摄 @param deviceType deviceType 摄像头设备类型(默认后置摄像头,前置摄像头需将 deviceType 初始值设置为 @"Front")
@param controller controller 当前 VC 控件
*/
- (void)openCameraVideoWithCameraDeviceType:(NSString *)deviceType AndController:(UIViewController *)controller {
// 判断是否可以打开照相机
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController *pickerCon = [[UIImagePickerController alloc] init];
pickerCon.delegate = self;
pickerCon.allowsEditing = YES;// 设置拍摄的照片是否允许编辑 // 摄像头
pickerCon.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerCon.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];// 将 mediaType 设置为所有支持的媒体类型
pickerCon.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;// 设置拍照类型(拍照 & 摄像)
pickerCon.videoQuality = UIImagePickerControllerQualityTypeHigh;// 设置拍摄视频的清晰度
if ([deviceType isEqualToString:@"Front"]) {// 设置使用手机摄像头类型
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceFront;// 设置使用手机前置摄像头
}
else {
pickerCon.cameraDevice = UIImagePickerControllerCameraDeviceRear;// 设置使用手机后置摄像头
} [controller presentViewController:pickerCon animated:YES completion:^{
NSLog(@"调用了 --- 摄像头");
}];
}
else {
[MBProgressHUD showCommonHudWithAlertString:@"没有摄像头" afterDelay:2.0 toView:controller.view];
}
} /**
调用相册 @param controller 当前 VC 控件
*/
- (void)openPhotoLibraryWithController:(UIViewController *)controller {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.allowsEditing = YES;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self; [controller presentViewController:imagePicker animated:YES completion:^{
NSLog(@"调用了 --- 相册");
}];
}
else {
[MBProgressHUD showCommonHudWithAlertString:@"无法打开相册" afterDelay:2.0 toView:controller.view];
}
} #pragma mark - UIImagePickerControllerDelegate
/**
拍照完成回调
@param picker 控件
@param info 数据
*/
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
NSLog(@"UIImagePickerControllerDelegate --- FinishPickingMedia"); // 获取拍摄数据的类型(照片 or 视频)
// NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; if (picker.sourceType == UIImagePickerControllerSourceTypeCamera || picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {// 图片 [mediaType isEqualToString:(NSString *)kUTTypeImage]
UIImage *theImg = nil;
if ([picker allowsEditing]) {// 判断图片是否允许修改
// 获取用户编辑之后的图像
theImg = [info objectForKey:UIImagePickerControllerEditedImage];
}
else {// 获取原图
theImg = [info objectForKey:UIImagePickerControllerOriginalImage];
} // 保存图片至相册中
UIImageWriteToSavedPhotosAlbum(theImg, self, nil, nil); // 图片后续处理相关
if ([self.delegate respondsToSelector:@selector(YHCameraCallBack:)]) {
[self.delegate YHCameraCallBack:theImg];
}
}
else {// 视频
// 获取视频文件 url
NSURL *urlMedia = [info objectForKey:UIImagePickerControllerMediaType];
// 创建 ALAssetsLibrary 对象并将视频保存到媒体库
ALAssetsLibrary *assetsLib = [[ALAssetsLibrary alloc] init];
// 将视频保存至相册
[assetsLib writeVideoAtPathToSavedPhotosAlbum:urlMedia completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"视频拍摄 --- 写入失败:%@", error);
}
else {
NSLog(@"视频拍摄 --- 写入成功");
}
}];
} [picker dismissViewControllerAnimated:YES completion:^{ }];
} /**
拍照页面取消选择的时候,调用该方法
@param picker 当前控件
*/
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:^{ }];
} @end
以上便是此次的分析内容,还望大神多多指教!
基于 UIImagePickerController 的拓展封装 - iOS的更多相关文章
- 封装ios静态库碰到的一些问题(一)
封装IOS动态库,碰到的第一个问题,就是资源文件的问题,如果将你的程序封装成为静态库,那么静态库中不会包含资源文件和xib文件,这个时候就需要自己封装bundle文件了,而笔者开发环境默认是xcode ...
- Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)
csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...
- 基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil
基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,把日常能用到的各种CRUD都进行了简化封装,让普通程序员只需关注业务即可,因为非常简单,故直接贴源代码,大家若需使用可以直 ...
- 基于PhoneGap3.4框架的iOS插件的实现
Phonegap 提供了iOS 设备的基础特性接口来供HTML页面调用,可是这些基础接口不能满足我们的一些特殊需求,所以有时候我们须要开发插件来扩展其功能. 基于PhoneGap3.4框架的iOS插件 ...
- 简单的基于promise的ajax封装
基于promise的ajax封装 //调用方式: /* ajaxPrmomise({ url:, method:, headers:{} }).then(res=>{}) */ ;(functi ...
- C#工具类OracleHelper,基于Oracle.ManagedDataAccess.Client封装
基于Oracle.ManagedDataAccess.Client封装的Oracle工具类OracleHelper,代码如下: using System; using System.Data; usi ...
- 基于EFCore3.0+Dapper 封装Repository
Wei.Repository 基于EFCore3.0+Dapper 封装Repository,实现UnitOfWork,提供基本的CURD操作,可直接注入泛型Repository,也可以继承Repos ...
- 基于Ant Design Vue封装一个表单控件
开源代码 https://github.com/naturefwvue/nf-vue3-ant 有缺点本来是写在最后的,但是博文写的似乎有点太长了,估计大家没时间往下看,于是就把有缺点写在前面了,不喜 ...
- iOS开发之网络请求(基于AFNetworking的再封装)
最近一直很忙也没有什么时间写博客了.放假了休息一下,就写一篇博客来总结一下最近做项目中出现过的问题吧!!! 首先,在项目中我的起到了什么作用,无非就是把美工(UI设计师)给我们的图显示出来,然后再和服 ...
随机推荐
- 5、栅格布局:ion-grid
/* --- html ----*/ <ion-content class="tabs"> <ion-grid> <h1>没有 warp 的 i ...
- JavaScript对象 原型
javascript对象就是一组数据和功能的集合,除原始类型(string.number.boolean.null.undefined)之外,其余都是对象. 可以通过对象直接量(字面量).new.和O ...
- [MySQL] - MySQL连接字符串总结
来源:http://blog.sina.com.cn/s/blog_5f0dab1e0100e4pv.html?retcode=0 一.MySQL Connector/ODBC 2.50 (MyODB ...
- java程序: 从kernel.ubuntu.com下载kernel - HttpURLConnection
用java实现从kernel.ubuntu.com下载内核的小工具 现在的最新的LTS版本是4.19,目前已经更新到4.19.13了. Kernel的更新通知里,经常有下面的陈述: 作为一个听劝的人, ...
- 《Hadoop权威指南》读书笔记1
<Hadoop权威指南>读书笔记 Day1 第一章 1.MapReduce适合一次写入.多次读取数据的应用,关系型数据库则更适合持续更新的数据集. 2.MapReduce是一种线性的可伸缩 ...
- Spring课程 Spring入门篇 4-4 Spring bean装配(下)之Autowired注解说明3 多选一 qualifier
本节主要讲述以下内容: 1 简述 2 代码演练 2.1 注解qualifier运用 1 简述 1.1 何种情况使用qualifier注解? a 按类型自动装配多个bean实例,可以用@qualifie ...
- Oracle JDBC 连接卡死后 Connection Reset
坑 这绝对是我碰计算机以来遇到的第一大坑! 症状: 在Linux主机上远程登录,执行一个简单的Oracle的JDBC连接程序(jar包),结果硬生生的卡在了连接建立验证阶段,然后等上几分钟后因为连接超 ...
- Bash 脚本语法
每次学了忘,忘了学,怎么记不住,因为长时间不用了 Bash 流程控制 循环 for循环 for item in $list do echo $item done 另一种与C语言类似的写法 ; i< ...
- mysql四-2:多表查询
一.介绍 本节主题: 多表连接查询 复合条件连接查询 子查询 准备表: #建表 create table department( id int, name ) ); create table empl ...
- Django——admin管理工具
一.admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTAL ...