I have a random problem that occurs when I present a UIImagePickerController
to capture a photo. Sometimes the preview screen is just black. (it can be the first time, can be the second time, or can be always, or even never). I can however see the camera controls, and the yellow squares for face detection.
If I wait some time (about 20 sec), the black preview disappear and the preview appears...
Here is what I can sometimes see in the logs :
Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
config : xcode 5.1.1, iPhone 5 / 5S, ios 7.0/7.1
Here is a code that reproduce the problem for me :
-(void) showCamera
{
UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
pickerController.allowsEditing = NO;
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
pickerController.cameraOverlayView = nil;
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
[topController presentViewController:pickerController animated:YES completion:nil];
}
Of course, for my real app, I test if there is a camera with :
[UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]);
I found several similar questions, but without any real answers :
I've tried what they suggest, without success.
Edit : here is some more code : As is said, I made a singleton class, subclassing UIImagePickerController :
@implementation BBImagePickerController
static BBImagePickerController *sharedInstance = nil;
+ (BBImagePickerController *) sharedInstance
{
if (!sharedInstance)
sharedInstance = [[BBImagePickerController alloc] init];
return sharedInstance;
}
@end
Then, I call it from the completion block of an action sheet, with UIActionSheet+BlocksKit :
UIActionSheet *actionSheetExt = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:cancel destructiveButtonTitle:nil otherButtonTitles:pickPic, takePic, nil];
[actionSheetExt showInView:presentingViewController.view];
[actionSheetExt bk_setDidDismissBlock:^(UIActionSheet *actionSheet, NSInteger click) {
if (click == actionSheet.cancelButtonIndex)
{
NSLog(@"the user cancelled the action");
return ;
}
BBImagePickerController *pickerController = [BBImagePickerController sharedInstance];
pickerController.allowsEditing = YES;
pickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
pickerController.delegate = self;
if (click == 1)
{ // get from library
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
else if (click == 2)
{
// take a picture
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
//[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
}
[presentingViewController presentViewController:pickerController animated:YES completion:^{
NSLog(@"BBImagePickerController presented");
// Black preview screen
}];
}];