基于 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
以上便是此次的分析内容,还望大神多多指教!