Hi,
I'm having some issues locking the focus and taking a flash photo on iPhone 10 (iOS 12.0). I've made the simplest camera app I can that turns Flash on using a AVCapturePhotoSettings object, locks focus on the AVCaptureDevice using [device setFocusMode:AVCaptureFocusModeLocked]; and then takes a picture using capturePhotoWithSettings.
Regardless of the focus lock, auto focus still often happens, particularly when the preview is out of focus. Am I missing a settings, or a new way to lock focus? I have no issues on the iPhone 6 with this code.
This is essentially the full app (i have dropped most the error checking in this example, but no errors pop up):
// ViewController.h
//#import
//@interface ViewController : UIViewController
//@end
#import
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic) AVCaptureSession *session;
@property (nonatomic) AVCapturePhotoOutput *stillImageOutput;
@property (nonatomic) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (weak, nonatomic) IBOutlet UIView *preview_view;
@property (weak, nonatomic) IBOutlet UIButton *take_picture_btn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void) viewDidAppear:(BOOL)animated
{
self.session = [[AVCaptureSession alloc] init];
self.session.sessionPreset = AVCaptureSessionPresetMedium;
self.videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
self.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspect;
self.videoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
[self.preview_view.layer addSublayer:self.videoPreviewLayer];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput* deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:NULL];
[self.session addInput:deviceInput];
self.stillImageOutput = [AVCapturePhotoOutput new];
[self.session addOutput:self.stillImageOutput];
[self.session commitConfiguration];
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(globalQueue, ^{
[self.session startRunning];
dispatch_async(dispatch_get_main_queue(), ^{
self.videoPreviewLayer.frame = self.preview_view.bounds;
});
});
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.session stopRunning];
}
- (IBAction)take_picture:(id)sender {
AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings];
settings.flashMode = AVCaptureFlashModeOn; // TURN ON FLASH
AVCaptureDevice* device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
[device setFocusMode:AVCaptureFocusModeLocked]; // LOCK FOCUS
[device unlockForConfiguration];
[self.stillImageOutput capturePhotoWithSettings:settings delegate:self];
}
- (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(nullable NSError *)error {
NSData *imageData = photo.fileDataRepresentation;
if (imageData) {
UIImage *image = [UIImage imageWithData:imageData];
UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);
}
}
@end
thanks for any help.
UDPATE: I've gone through Apples technical support. They have recognised this as a bug in the API on iPhone 8 and above. The auto-focus is not bypassed correctly when fixing the lens position. As of iOS 12.1.4 this is still an issue, but hopeful for a fix. No work around found as of yet.