I used this code to achieve Tap-to-Focus in iOS custom camera App, but it isn't working. Here's the code
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touchPer = touches.anyObject() as UITouch
let screenSize = UIScreen.mainScreen().bounds.size
var focus_x = touchPer.locationInView(self.view).x / screenSize.width
var focus_y = touchPer.locationInView(self.view).y / screenSize.height
if let device = captureDevice {
if(device.lockForConfiguration(nil)) {
device.focusMode = AVCaptureFocusMode.ContinuousAutoFocus
device.focusPointOfInterest = CGPointMake(focus_x, focus_y)
device.exposureMode = AVCaptureExposureMode.ContinuousAutoExposure
device.unlockForConfiguration()
}
}
}
You should read Apple docs on
focusPointOfInterest
, which says three important things:Here is an implementation which does all of that:
I don't why this works, but it did.
The better way to set focus point of interest:
first calculate the point of interest:
after that set the focus point of interest :
Swift 3.0 Solution
Converted Cody's answer into a working solution with Swift 3.
You have to call the methods in the right order:
Set the point of interest before setting the focus mode else the focus will be made on the previous point of interest.
The same apply for
exposurePointOfInterest
.With a
videoView: UIView
displaying the video, andcameraDevice: AVCaptureDevice
, the following seems to work for me:Note that I had to swap the
x
andy
coordinates, and remap thex
coord from 1 to 0 instead of 0 to 1 —not sure why that should be the case but it seems to be necessary to get it to work right (though it's a little tricky to test it too).Edit: Apple's documentation explains the reason for the coordinate transformation.
In my example I had been using
.ContinuousAutoFocus
and.ContinuousAutoExposure
, but the documentation indicates.AutoFocus
is the right choice. Oddly the documentation makes no mention of.AutoExpose
, but I'm using it in my code and it works fine.I also modified my example code to include
.focusPointOfInterestSupported
and.exposurePointOfInterestSupported
tests — the documentation also mentions using theisFocusModeSupported:
andisExposureModeSupported:
methods for a given focus/exposure mode to test whether it is available on a given device before setting it, but I assume if the device supports the point of interest modes then it also supports the auto modes. It all seems to work fine in my app.