美文网首页iOS高级功能实现
自定义UIImagecontroller实践 2022-04-0

自定义UIImagecontroller实践 2022-04-0

作者: 勇往直前888 | 来源:发表于2022-04-11 19:30 被阅读0次

    需求

    在拍照过程中检测手机是否水平。水平的时候允许拍照,倾斜的时候不能拍照。

    思路

    • UIimagecontroller一般用来拍照,take photo按钮以点,就拍照了,然后就退出拍照界面了。我们基本上已经习惯了这套,所以对于上面的需求感觉很棘手。

    • showsCameraControls 这个属性可以隐藏系统给的按钮,比如照相,切换摄像头,闪光灯等等。

    • cameraOverlayView 这个属性可以在拍照页面上加一个自定义视图。
      通过这两个属性,感觉可以实现以上需求:
      就是隐藏默认的按钮,在自定义视图上提供自定义的按钮。

    UIImagecontroller简介

    • 定义:继承自UINavigationController,这个有点出乎意料
      @interface UIImagePickerController : UINavigationController <NSCoding>
      @interface UINavigationController : UIViewController

    • sourceType:来源;一直以来支持相机和照片库。不过现在改了,今后将专注于相机;照片部分将移到PHPicker;这样改是有道理的,把拍照和取照片分开,符合设计模式中的职责单一原则。

    typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
        UIImagePickerControllerSourceTypePhotoLibrary API_DEPRECATED("Will be removed in a future release, use PHPicker.", ios(2, API_TO_BE_DEPRECATED)),
        UIImagePickerControllerSourceTypeCamera,
        UIImagePickerControllerSourceTypeSavedPhotosAlbum API_DEPRECATED("Will be removed in a future release, use PHPicker.", ios(2, API_TO_BE_DEPRECATED)),
    } API_UNAVAILABLE(tvos);
    

    不是所有的设备都支持相机。由于UINavigationController还支持照片库,所以设置sourceType是首要任务。下面的方法和属性配合起来用比较好。

    + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;                 // returns YES if source is available (i.e. camera present)
    
    @property(nonatomic)           UIImagePickerControllerSourceType     sourceType;                                                        // default value is UIImagePickerControllerSourceTypePhotoLibrary.
    
    • CaptureMode:其实就是拍照片还是拍视频;
    typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraCaptureMode) {
        UIImagePickerControllerCameraCaptureModePhoto,
        UIImagePickerControllerCameraCaptureModeVideo
    } API_UNAVAILABLE(tvos);
    
    • @property(nonatomic,copy) NSArray<NSString *> *mediaTypes; // default value is an array containing kUTTypeImage.
      这个属性设置支持那些,默认只有照片;如果要照片和视频都支持,需要设置为@[@"public.image", @"public.movie"]
    • @property(nonatomic) UIImagePickerControllerCameraCaptureMode cameraCaptureMode API_AVAILABLE(ios(4.0)); // default is UIImagePickerControllerCameraCaptureModePhoto
      这个属性设置当前是拍照片还是拍视频,默认是拍照片
    • allowsEditing:是否可编辑;默认不能编辑,一般也没什么用
    @property(nonatomic)           BOOL                                  allowsEditing API_AVAILABLE(ios(3.1));     // replacement for -allowsImageEditing; default value is NO.
    
    • 摄像头:前置还是后置
    typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
        UIImagePickerControllerCameraDeviceRear,
        UIImagePickerControllerCameraDeviceFront
    } API_UNAVAILABLE(tvos);
    
    @property(nonatomic) UIImagePickerControllerCameraDevice      cameraDevice      API_AVAILABLE(ios(4.0)); // default is UIImagePickerControllerCameraDeviceRear
    
    • 闪光灯:自动,关闭,打开
    typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraFlashMode) {
        UIImagePickerControllerCameraFlashModeOff  = -1,
        UIImagePickerControllerCameraFlashModeAuto = 0,
        UIImagePickerControllerCameraFlashModeOn   = 1
    } API_UNAVAILABLE(tvos);
    
    @property(nonatomic) UIImagePickerControllerCameraFlashMode   cameraFlashMode   API_AVAILABLE(ios(4.0)); // default is UIImagePickerControllerCameraFlashModeAuto. 
    
    • 自定义图层:默认是不提供自定义图层,采用系统提供的功能按钮
    // camera additions available only if sourceType is UIImagePickerControllerSourceTypeCamera.
    @property(nonatomic)           BOOL                                  showsCameraControls API_AVAILABLE(ios(3.1));   // set to NO to hide all standard camera UI. default is YES
    @property(nullable, nonatomic,strong) __kindof UIView                *cameraOverlayView  API_AVAILABLE(ios(3.1));   // set a view to overlay the preview view.
    @property(nonatomic)           CGAffineTransform                     cameraViewTransform API_AVAILABLE(ios(3.1));   // set the transform of the preview view.
    

    自定义图层

    • 这里不使用系统提供的,自己给个自定义视图
            // 不用系统提供的功能按钮,采用自定义的视图来做控制
            self.showsCameraControls = NO;
            self.cameraOverlayView = self.customerView;
    
    • 这样做可以自己来控制拍照功能,提供的API是
    - (void)takePicture API_AVAILABLE(ios(3.1));                                                   
    // programmatically initiates still image capture. ignored if image capture is in-flight.
    // clients can initiate additional captures after receiving -imagePickerController:didFinishPickingMediaWithInfo: delegate callback
    
    • 问题:隐藏系统按钮,提供自定义视图,比较下来,拍照功能受到了影响,比如,对焦的小矩形框就没有了,体验很差。

    小结

    本来的想法是采用在自定义图层cameraOverlayView上添加操作按钮来实现需求。但是体验下来,还不如直接采用默认的按钮来做效果更好,代码也更简洁。

    至于要更多地控制相机的细节,咨询过大神,回应说应该用更底层API,比如AVCaptureSession之类的。

    参考文章

    iOS UIImagePickerController轻松调用相机详细介绍

    iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

    iOS设备的重力感应

    iOS 重力感应 学习1 陀螺仪 水平仪 指南针

    相关文章

      网友评论

        本文标题:自定义UIImagecontroller实践 2022-04-0

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