Как узнать, когда фонарь AVCaptureDevice выключается?

У меня есть контроллер представления на основе AVCam, и я добавил UIButton для переключения света факела. Вот код, который выполняет это:

- (IBAction)toggleTorchLight:(id)sender {
// See: http://stackoverflow.com/questions/11726543/how-to-turn-flashlight-on-off-using-one-button
AVCaptureDevice *flashLight = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([flashLight isTorchAvailable] && [flashLight isTorchModeSupported:AVCaptureTorchModeOn]){
    if ([flashLight lockForConfiguration:nil]){
        if ([flashLight isTorchActive]) {
            [flashLight setTorchMode:AVCaptureTorchModeOff];
            [(UIButton *)sender setTintColor:[UIColor blackColor]];
        }
        else {
            [flashLight setTorchMode:AVCaptureTorchModeOn];
            [(UIButton *)sender setTintColor:[UIColor yellowColor]];
        }
        [flashLight unlockForConfiguration];
    }
}

Вы заметите, что я включаю желтую кнопку, когда горит свет. Проблема в том, что фонарик также выключается, когда приложение отправляется в фоновый режим, когда изменяется контроллер представления, когда представлен контроллер оповещения и т. д. Эти события выключают свет факела, но мне также нужно сделать кнопку опять черный.

Вместо того, чтобы делать кнопку черной для каждого из этих отдельных сценариев, есть ли простой способ, например, получение уведомления, когда свет выключается? Я пробовал AVCaptureDeviceWasDisconnectedNotification, переопределяя becomeFirstResponder и viewDidDisappear, ни один из них не работал.

Какие-либо предложения?


person Aaron King    schedule 22.11.2016    source источник
comment
Вы пытались запустить собственное уведомление, используя состояния AppDelegate? applicationWillResignActive например   -  person Nathaniel    schedule 22.11.2016
comment
Вы можете использовать KVO для наблюдения за torchActive.   -  person Rhythmic Fistman    schedule 23.11.2016
comment
@RhythmicFistman KVO сработало отлично! Использовал это в качестве руководства   -  person Aaron King    schedule 25.11.2016
comment
Отлично - почему бы вам не добавить свой код в качестве ответа и не принять его?   -  person Rhythmic Fistman    schedule 25.11.2016


Ответы (1)


Сначала определите контекстный адрес:

static void * TorchActiveContext = &TorchActiveContext;

Затем в методе addObservers:

AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[videoDevice addObserver:self forKeyPath:@"torchActive" options:NSKeyValueObservingOptionNew context:TorchActiveContext];

В методе removeObservers:

AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[videoDevice removeObserver:self forKeyPath:@"torchActive" context:TorchActiveContext];

In observeValueForKeyPath

if (context == TorchActiveContext) {
    UIColor *color = ((AVCaptureDevice*)object).torchActive ? [UIColor yellowColor] : [UIColor blackColor];
    [self.torchLightButton setTintColor:color];
}
person Aaron King    schedule 25.11.2016