Ответ 1
Сначала это звучит очень сложно: но это оказалось очень просто, Apple уже сделала 99% работы для нас. Все, что вам нужно сделать, это установить "subjectAreaChangeMonitoringEnabled" и зарегистрировать KVO в "AVCaptureDeviceSubjectAreaDidChangeNotification"! В документах iOS 6.1:
Значение этого свойства указывает, должен ли приемник контролировать область видеообъекта для изменений, таких как изменения освещения, существенное движение и т.д. Если мониторинг изменения предметной области включен, объект устройства захвата отправляет AVCaptureDeviceSubjectAreaDidChangeNotification всякий раз, когда он обнаруживает изменить предметную область, и в это время заинтересованный клиент может хотите перефокусироваться, настроить экспозицию, баланс белого и т.д.
Прежде чем изменять значение этого свойства, вы должны позвонить lockForConfiguration: для получения эксклюзивного доступа к устройствам свойства конфигурации. Если вы этого не сделаете, установите значение этого свойство вызывает исключение. Когда вы закончите настройку устройство, вызовите unlockForConfiguration, чтобы освободить блокировку и разрешить другие устройства для настройки параметров.
Вы можете наблюдать за изменениями этого свойства с использованием значения ключа наблюдения.
(Еще лучше, вам не нужно обрабатывать много угловых случаев. Что делать, если устройство находится в середине "adjustingFocus" в POI, а контент изменился? Вы не хотите, чтобы устройство возвращалось к автофокусу в центре, и хотите, чтобы действие фокуса закончилось. Сообщение об изменении области было вызвано только после того, как фокус сделан.)
Пример фрагмента кода из моего проекта. (Структура соответствует официальному примеру AVFoundation AVCam, поэтому вы можете легко их установить и попробовать):
// CameraCaptureManager.m
@property (nonatomic, strong) AVCaptureDevice *backFacingCamera;
- (id) init{
self = [super init];
if (self){
// TODO: more of your setup code for AVFoundation capture session
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if (device.position == AVCaptureDevicePositionBack){
self.backFacingCamera = device;
}
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
void (^subjectAreaDidChangeBlock)(NSNotification *) = ^(NSNotification *notification) {
if (self.videoInput.device.focusMode == AVCaptureFocusModeLocked ){
// All you need to do is set the continuous focus at the center. This is the same behavior as
// in the stock Camera app
[self continuousFocusAtPoint:CGPointMake(.5f, .5f)];
}
};
self.subjectAreaDidChangeObserver = [notificationCenter addObserverForName:AVCaptureDeviceSubjectAreaDidChangeNotification
object:nil
queue:nil
usingBlock:subjectAreaDidChangeBlock];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[self addObserver:self forKeyPath:keyPathAdjustingFocus options:NSKeyValueObservingOptionNew context:NULL];
}
return self;
}
-(void) dealloc{
// Remove the observer when done
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self.deviceOrientationDidChangeObserver];
}
- (BOOL) setupSession{
BOOL sucess = NO;
if ([self.backFacingCamera lockForConfiguration:nil]){
// Turn on subject area change monitoring
self.backFacingCamera.subjectAreaChangeMonitoringEnabled = YES;
}
[self.backFacingCamera unlockForConfiguration];
// TODO: Setup add input etc...
return sucess;
}