大部分PhotoPicker控件没有拍照功能,在其基础上增加拍照功能,修改第三方的照片选择
代码:
因为我这里只是部分地方需要有拍照,其他地方还是希望保持原本的功能。
首先定义一个属性:
@property BOOL withCamera;
在.h里面增加代理方法(因为我用的选择器本身选择图片之后的回调使用的是图片的地址,相机拍照的话回调应该是图片数据本身):
/**
采集图片|视频完成; 这个是原本的选择器代理方法
@param photoPicker 照片采集器
@param medias 多媒体数组(图片|视频)
*/
- (void) jf_photoPicker:(JFPhotoPickerViewController*)photoPicker didPickedMedias:(NSArray<JFPhotoPickerModel*>*)medias;
/**
拍摄图片|完成;这个是我新增的方法
@param photoPicker 照片采集器
@param images 多媒体数组(图片|视频)
*/
- (void) jf_photoPicker:(JFPhotoPickerViewController*)photoPicker didPickedImages:(NSArray<UIImage*>*)images;
然后是相册展示页面增加拍摄按钮,一般来说,相册展示的时候都是用的UICollectionView,我们在第一行更改为拍照按钮,并更改选择方法:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (_withCamera) {
//返回相册数量+1
return [self.viewModel jf_numberOfRowsInSection:section] +1;
}
//返回相册数量
return [self.viewModel jf_numberOfRowsInSection:section];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
//这里不同的相册选择器应该有不同的处理,大概思路是:
NSIndexPath *cellIndexPath;
if (_withCamera) {
if (indexPath.row == 0) {
//如果带拍照,第一行的时候显示默认拍照图片。而不是相册图片
JFPhotoPickerCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"JFPhotoPickerCell" forIndexPath:indexPath];
[cell showDefine];
return cell;
}else{
// 我们增加了一行cell,但是数据数组并没有增加数据所以做一个数据移位
cellIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:0];
}
}
indexPath = cellIndexPath;
//数据移位完成,后面的代码基本不用动
JFPhotoPickerCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"JFPhotoPickerCell" forIndexPath:indexPath];
JFPhotoPickerModel* model = [self.viewModel jf_modelForRowAtIndexPath:indexPath];
cell.model = model;
cell.didUpdateSelectState = ^(JFPhotoPickerCell * _Nonnull cell, JFPhotoPickerModel * _Nonnull model) {
。。。。。。
};
return cell;
}
点击回调:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
WeakSelf(wself);
NSIndexPath *cellIndexPath;
if (_withCamera) {
if (indexPath.row == 0) {
NSLog(@"拍摄");
[self showCamera];
return;
}else{
//和上面方法一样,数据移位
cellIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:0];
}
}
indexPath = cellIndexPath;
//数据移位完成,后面基本不用动。
JFPhotoPickerModel* modelfirst = [self.viewModel jf_modelForRowAtIndexPath:indexPath];
if (modelfirst.asset.mediaType == PHAssetMediaTypeImage) {
........
} else {
......
}
}
相机相关代码,:
-(void)showCamera
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
// 设置代理
imagePickerController.delegate = self;
// 是否显示裁剪框编辑(默认为NO),等于YES的时候,照片拍摄完成可以进行裁剪
imagePickerController.allowsEditing = NO;
// 设置照片来源为相机
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
// 设置进入相机时使用前置或后置摄像头
imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
// 展示选取照片控制器
[self presentViewController:imagePickerController animated:YES completion:nil];
}
#pragma mark - UIImagePickerControllerDelegate
// 完成图片的选取后调用的方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// 选取完图片后跳转回原控制器
[picker dismissViewControllerAnimated:YES completion:nil];
/* 此处参数 info 是一个字典,下面是字典中的键值 (从相机获取的图片和相册获取的图片时,两者的info值不尽相同)
* UIImagePickerControllerMediaType; // 媒体类型
* UIImagePickerControllerOriginalImage; // 原始图片
* UIImagePickerControllerEditedImage; // 裁剪后图片
* UIImagePickerControllerCropRect; // 图片裁剪区域(CGRect)
* UIImagePickerControllerMediaURL; // 媒体的URL
* UIImagePickerControllerReferenceURL // 原件的URL
* UIImagePickerControllerMediaMetadata // 当数据来源是相机时,此值才有效
*/
// 从info中将图片取出,并加载到imageView当中
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
if (!image) {
return;
}
WeakSelf(wself);
self.navigationItem.rightBarButtonItem.enabled = NO;
//这里实现增加的通过拍照获取图片的代理方法
if (wself.delegate && [wself.delegate respondsToSelector:@selector(jf_photoPicker:didPickedImages:)]) {
NSMutableArray *ary = [NSMutableArray new];
[ary addObject:image];
[wself.delegate jf_photoPicker:wself didPickedImages:ary];
[wself clickedCancel:nil];
}
wself.navigationItem.rightBarButtonItem.enabled = YES;
// self.imageView.image = image;
// // 创建保存图像时需要传入的选择器对象(回调方法格式固定)
// SEL selectorToCall = @selector(image:didFinishSavingWithError:contextInfo:);
// // 将图像保存到相册(第三个参数需要传入上面格式的选择器对象)
// UIImageWriteToSavedPhotosAlbum(image, self, selectorToCall, NULL);
}
// 取消选取调用的方法
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:YES completion:nil];
}
相机相关代码来自:
https://www.jianshu.com/p/79a3690ef63e
网友评论