How to turn flashlight on/off using one button?

Viewed 16360

I can turn my flashlight on with one button and turn it off with another. But I want to do it with only one button. However, I don't have a framework which allows me to use the bool isSelected method. So I'm quite clueless on how to merge both functions together in one button.

Here's the code which works:

-(void)onButtonPressed 
{

AVCaptureDevice *flashLight = [AVCaptureDevice 
defaultDeviceWithMediaType:AVMediaTypeVideo];
if([flashLight isTorchAvailable] && [flashLight
isTorchModeSupported:AVCaptureTorchModeOn])
{
    BOOL success = [flashLight lockForConfiguration:nil];
    if(success){
        [flashLight setTorchMode:AVCaptureTorchModeOn];
        [flashLight unlockForConfiguration];
    }
}

}

I use this to turn the flashlight off.

-(void)offButtonPressed {

AVCaptureDevice *flashLight = [AVCaptureDevice
defaultDeviceWithMediaType:AVMediaTypeVideo];
if([flashLight isTorchAvailable] && [flashLight
isTorchModeSupported:AVCaptureTorchModeOn])
{
    BOOL success = [flashLight lockForConfiguration:nil];
    if(success){
        [flashLight setTorchMode:AVCaptureTorchModeOff];
        [flashLight unlockForConfiguration];
    }
}


}

I'm not particular about the way it's done. As long as the flashlight turns on with the first tap and turns off on the second, I couldn't care less about the method.

However, I'm using barbuttonitems made programatically, so please don't give me IBAction methods. I'd also appreciate it if the method suggested is as simple as possible, I think the way I'm using the flashlight right now is overly complex.

7 Answers

Solution for Swift 5 based on Chuy47's answer:

import Foundation
import AVFoundation

extension AVCaptureDevice {

    /// toggles the device's flashlight, if possible
    static func toggleFlashlight() {
        guard let device = AVCaptureDevice.default(for: AVMediaType.video), device.hasTorch else { return }
        do {
            try device.lockForConfiguration()
            let torchOn = !device.isTorchActive
            try device.setTorchModeOn(level: 1.0)
            device.torchMode = torchOn ? .on : .off
            device.unlockForConfiguration()
        } catch {
            print("Error toggling Flashlight: \(error)")
        }
    }
}

Swift 5 version

@IBAction func toggleTorch() {
    guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else {
        showTorchNotSupported()
        return
    }
    
    do {
        try device.lockForConfiguration()
        let torchOn = !device.isTorchActive
        try device.setTorchModeOn(level: 1.0)
        device.torchMode = torchOn ? .on : .off
        device.unlockForConfiguration()
    } catch {
        showTorchNotSupported()
    }
}

private func showTorchNotSupported() {
    let alertController = UIAlertController(title: "Flashlight is not supported", message: nil, preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Understand", style: .default, handler: nil))
    present(alertController, animated: true)
}
Related