美文网首页
iOS 为相册选择器添加拍照功能

iOS 为相册选择器添加拍照功能

作者: 万年老参 | 来源:发表于2020-03-05 19:54 被阅读0次

    大部分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

    相关文章

      网友评论

          本文标题:iOS 为相册选择器添加拍照功能

          本文链接:https://www.haomeiwen.com/subject/zyngrhtx.html