Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing flash mode with a custom camera overlay

I am using the UIImagePickerController with a custom camera overlay view and wish to add a custom button to toggle the flash mode between auto, on, and off. Here is the method the button calls:

- (void)didTapFlash:(id)sender
{
    if (self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeAuto)
    {
        [imagePickerController setCameraFlashMode:UIImagePickerControllerCameraFlashModeOn];
        [self.flashButton setImage:[UIImage imageNamed:@"flashIconOn.png"] forState:UIControlStateNormal];
    }
    else if (self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeOn)
    {
        self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
        [self.flashButton setImage:[UIImage imageNamed:@"flashIconOff.png"] forState:UIControlStateNormal];
    }
    else if (self.imagePickerController.cameraFlashMode == UIImagePickerControllerCameraFlashModeOff)
    {
        self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
        [self.flashButton setImage:[UIImage imageNamed:@"flashIconAuto.png"] forState:UIControlStateNormal];
    }
}

The problem is this doesn't work. The value of self.imagePickerController.cameraFlashMode never changes once the controller is presented. The flash value can be changed before it is presented but, once it is, it will always return a value of 0 (Auto). The strange part is, even though the value doesn't change, the flash behaves as if it does so if I change the above code to:

- (void)didTapFlash:(id)sender
{
    if (flashButton.tag == 0)
    {
        [imagePickerController setCameraFlashMode:UIImagePickerControllerCameraFlashModeOn];
        self.flashButton.tag = 1;
        [self.flashButton setImage:[UIImage imageNamed:@"flashIconOn.png"] forState:UIControlStateNormal];
    }
    else if (flashButton.tag == 1)
    {
        self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
        self.flashButton.tag = -1;
        [self.flashButton setImage:[UIImage imageNamed:@"flashIconOff.png"] forState:UIControlStateNormal];
    }
    else if (flashButton.tag == -1)
    {
        self.imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
        self.flashButton.tag = 0;
        [self.flashButton setImage:[UIImage imageNamed:@"flashIconAuto.png"] forState:UIControlStateNormal];
    }
} 

Everything works as expected. (the flashButton.tag is just storing the flash value)

Does anyone know what is happening here? Why does the value of cameraFlashMode always 0 (both in NSLog statements and when checked directly through the debugger) even though the flash is behaving as though it is set properly?

like image 986
Matt Rundle Avatar asked Nov 11 '22 14:11

Matt Rundle


1 Answers

It seems to be a bug in latest iOS version,

you'll notice that it will work with enabling the flag of

 self.picker.showsCameraControls = true

but it shows the native camera control to your overlayview, so i hacked it with this code:

 self.picker.showsCameraControls = true
 self.picker.cameraFlashMode = .On
 self.picker.showsCameraControls = false

It is fast enough to not disturb user with the showing and hiding controls. It Worked for me and i'm sure it will work in your case too!

like image 131
Steve Avatar answered Nov 15 '22 07:11

Steve