需求
在拍照过程中检测手机是否水平。水平的时候允许拍照,倾斜的时候不能拍照。
思路
-
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
之类的。
网友评论