iOS 7 UIImagePickerController has black preview

Heavy_Bullets picture Heavy_Bullets · Sep 29, 2013 · Viewed 11k times · Source

I have a UIImagePickerController being called with sourceType camera and 80% of the time I get a black preview. If I wait, let's say around 30 seconds, I get a good preview and it will be good for around 50% of the time, then it can break again.

The image in question is very similar to this. iDevice camera shows black instead of preview

Other people imply that GCD might be causing some issues with the camera, and that updates to the UI while the image picker is being loaded break it. I put a lock on every GCD block that calls the main thread for this purpose.

This is an example of an image that rotates to simulate an activity indicator.

-(void)animateLoadingImage {

if (isMainThreadBlocked) {
    return;
}

self.radians += M_PI_4 / 2;
[UIView beginAnimations:@"progress rotation" context:nil];
[UIView setAnimationDuration:.1];
self.loadingImageView.transform = CGAffineTransformMakeRotation(self.radians);
[UIView commitAnimations];


}

PS: 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.

This shows ALWAYS when I try to open the picker controller, but it shows it even if the camera shows the preview correctly. I don't think the error is around here but this bugs me a lot also.

Answer

Bart picture Bart · Nov 15, 2013

During one of my recent projects I had this same (or similar) issue, namely the Camera preview showing a black screen when using UIImagePickerController on iOS7 (iPad).

What I discovered is that GCD in itself is not the problem. The problem occurs when you try to use anything at all from the UIKit framework in a thread other than the main thread (as part of an NSOperation).

First of all, let me start by saying that it is clear to me that you shouldn't do this to begin with. In my specific case, however, I had no choice. Since I think that there's a good chance that other people might be experiencing the same weird UIImagePickerController camera behaviour with the same cause, I made up some very simple example code explaining what's going on.

You can find it here: https://github.com/idamediafoundry/CameraTest

The ViewController shows 2 simple buttons. One calls UIImagePickerController, showing the camera, the other starts some GCD operations doing a simple task. If you just open the camera, everything works fine. If you first start the operations and then open the camera, the black preview issue occurs.

Again, you shouldn't call UIKit in anything but the main thread. But I don't think it's normal that breaking this rule causes the camera to malfunction when opening it later in the main thread as part of a completely different flow, right?

Hope this helps.