iOS 7 UIImagePicker preview black screen
Asked Answered
A

3

26

When i try to load camera from my code, camera preview is black. If I wait for 10-20 seconds it will show real camera preview. I found several questions and some of them suggest that running some other code in background should be the reason for this. However I don't have any code running in background. How should I fix this?

This is my code where I run camera

UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];

photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:photoPicker animated:YES completion:NULL];
Anthraquinone answered 19/2, 2014 at 17:49 Comment(12)
This code looks right - I would suggest trying this: dispatch_async(dispatch_get_main_queue(), ^{ <your current code here> }); and seeing if anything changes. If it works right, that means that you are running the code in the background somewhereRangoon
You can also set a breakpoint on any of the lines you posted, and look in the Xcode sidebar when you hit the breakpoint to see what thread you are on.Trakas
@Rangoon I have tried your code and nothing changed.Anthraquinone
@ZevEisenberg also tried with breakpoint and it says I am on Thread 1.Anthraquinone
Welcome to the crap that is iOS 7's UIImagePicker. For absolutely no apparent reason, sometimes (more often than not) you get a black preview screen. Sometimes it goes away after awhile and you get the camera preview, and sometimes it doesn't. Mind you, the exact same code works seamlessly on iOS 6. I have spent hours trying to figure this out. This question deserves some serious attention! It makes us developers look like we don't know how to program, when it is entirely in Apple's hands. I am thinking of writing my own image capture with lower level API's.Microgroove
One more thing, if you take a picture while the screen is black, it still shows up fine, so it's just the preview.Microgroove
Yes, it shows up fine when I take the picture. I have also tried implementing AVFoundation camera and it also needs 10-20 seconds until it shows preview. I can't believe there is no solution for this issue.Anthraquinone
Check my answer: preview runs on main thread so borks easy. You have to implement a semaphore to lockout shared access or wait for Apple to fix itSabayon
maybe use completion:nil instead of NULL. I don't know if it's a difference but I have never used or seen NULL in a completion.Packaging
There is a similar question on other thread on SO #16747339 Try creating a singleton instance of UIImagePickerController and use it. The possible problem possibly can occurs when an app uses many threads or dispatch queuesArgumentation
Does your app uses multiple treads or dispatch queues. If so then check if you are not showing the UIImagePicker on main thread.Argumentation
possible duplicate of iOS 7 UIImagePickerController has black previewAmmadis
M
21

About 5 months ago my team discovered a memory leak with UIImageViewController in iOS7. Each instantiation slowed down the app exponentially (i.e. first alloc-init had a 1 second delay, second had a 2 second delay, third had a 5 second delay). Eventually, we were having 30-60 delays (similar to what you're experiencing).

We resolved the issue by subclassing UIImagePickerController and making it a Singleton. That way it was only ever initialized once. Now our delay is minimal and we avoid the leak. If subclassing isn't an option, try a class property in your viewController and just lazy load it like so.

-(UIImagePickerController *)imagePicker{
    if(!_imagePicker){
        _imagePicker = [[UIImagePickerController alloc]init];
        _imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }
    return _imagePicker;
}

Then you can just call it later like:

[self presentViewController:self.imagePicker animated:YES completion:nil];
Muskellunge answered 24/2, 2014 at 22:58 Comment(3)
Thank you @eckyzero for your answer. I have a feeling that it reduced some time I have to wait for black screen to remove, but it hasn't been completely resolved. It seems that it is a more responsive with your codeAnthraquinone
This isn't a complete fix, but it certainly helps. —It doesn't feel like too much to ask for Apple to put this issue at the very top of their list of fixes for the next update of iOS 7. It is really important to have such key features of apps work quickly and efficiently! Furthermore, this isn't the only bug with the UIImagePickerController in iOS 7.Microgroove
I'm glad to have helped a little bit and I couldn't agree with you more. Do you know if anyone has filed a bug with Apple?Muskellunge
S
2

Had this myself - it happens if something is running on the main dispatch thread - are you resizing images by any chance?

It puts the preview onto the main thread and if something is using it, you get a black screen. It's a bug and the workaround is to either take over the main thread or to disable the photo picker until the queue is free

Sabayon answered 24/2, 2014 at 20:29 Comment(3)
In this view I am using UICollectionView and yes I am resizing images as well. I have checked and my UIImagePicker code is running on the main thread. Do you have any ideas could be there something wrong with resizing images?Anthraquinone
I'm looking for a solution myself - at the moment is seems that it is an internal bug. I can't seem to resize images on another thread or use AVAssetWriter at the same time: very annoyingSabayon
I'm facing a similar problem (closed due to memory issues), but only if I resize the captured image. What does this mean for me? No image resizing here?Proud
R
-1

This Should work for you:

    - (void)cameraViewPickerController:(UIImagePickerController *)picker
{
    [self startCameraControllerFromViewController: picker
                                    usingDelegate: self];
}


- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
                                   usingDelegate: (id <UIImagePickerControllerDelegate,
                                                   UINavigationControllerDelegate>) delegate {

    if (([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypeCamera] == NO)
        || (delegate == nil)
        || (controller == nil))
        return NO;


    UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
    cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;

    // Displays a control that allows the user to choose movie capture
    cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, (NSString *) kUTTypeMovie,nil];

    // Hides the controls for moving & scaling pictures, or for
    // trimming movies. To instead show the controls, use YES.
    cameraUI.allowsEditing = NO;

    cameraUI.delegate = delegate;

    [controller presentViewController:cameraUI animated:YES completion:nil];
    return YES;
}
Rattrap answered 3/3, 2014 at 12:18 Comment(1)
I also solved issue. I was having issue of background thread.Uploading images task i put it in background thread. i put it back on main thread and working fine.Cassey

© 2022 - 2024 — McMap. All rights reserved.