6

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 
    }];
}];
Community
  • 1
  • 1
Diwann
  • 888
  • 1
  • 8
  • 28

0 Answers0