iOS 8 Snapshotting a view that has not been rendered results in an empty snapshot

Objective CIos8Uiimagepickercontroller

Objective C Problem Overview


In iOS 8 I am having problem capturing images from camera till now I am using this code for

UIImagePickerController *controller=[[UIImagePickerController alloc] init];
controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
controller.delegate=(id)self;
controller.sourceType=UIImagePickerControllerSourceTypeCamera;
[self presentViewController:controller animated:YES completion:nil];

But in iOS 8 I am getting this:

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.

I have tried with the solution provided by This Post with

@property (strong,nonatomic)UIImagePickerController *controller;

_controller=[[UIImagePickerController alloc] init];
_controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
_controller.delegate=(id)self;
_controller.sourceType=UIImagePickerControllerSourceTypeCamera;
_[self presentViewController:controller animated:YES completion:nil];

and this

...
controller.modalPresentationStyle=UIModalPresentationFullScreen;
or
controller.modalPresentationStyle=UIModalPresentationCurrentContext;
...

and this

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self presentViewController:controller animated:YES completion:nil];
});

and this

[self presentViewController:controller animated:YES completion:NULL];

and this

[self presentViewController:controller animated:YES completion:^{
    
}];

any idea?

Objective C Solutions


Solution 1 - Objective C

I'm pretty sure this is just a bug in iOS 8.0. It's reproducible with the simplest of POC apps that does nothing more than attempt to present a UIImagePickerController like you're doing above. Furthermore, there's no alternative pattern to displaying the image picker/camera, to my knowledge. You can even download Apple's Using UIImagePickerController sample app, run it, and it will generate the same error out of the box.

That said, the functionality still works for me. Other than the warning/error, do you have issues with the functioning of your app?

Solution 2 - Objective C

I was struggling with this issue for several hours, i have read every relevant topic and found out that the error was caused because under the privacy settings of my device, the camera access to my app was blocked!!! I have never denied access to camera and i don't know how it was blocked but that was the problem!

Solution 3 - Objective C

I don't have enough reputation points to comment on @greg's answer above, so will add my observations here. I have a Swift project for both iPad and iPhone. I have a method inside my main view controller (relevant bit below). When I test this on a phone, everything works properly and no warnings are generated. When I run it on an iPad, everything works properly but I see the warning about snapshotting the view. The interesting bit, however, is that when I run on an iPad without using the popover controller, everything works properly with no warning. Unfortunately, Apple mandates that the image picker must be used within a popover on iPad, if the camera is not being used.

    dispatch_async(dispatch_get_main_queue(), {
        let imagePicker: UIImagePickerController = UIImagePickerController();
        imagePicker.sourceType = UIImagePickerControllerSourceType.SavedPhotosAlbum;
        imagePicker.mediaTypes = [kUTTypeImage];
        imagePicker.allowsEditing = false;
        imagePicker.delegate = self;
        
        if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){ // on a tablet, the image picker is supposed to be in a popover
            let popRect: CGRect = buttonRect;
            let popover: UIPopoverController = UIPopoverController(contentViewController: imagePicker);
            popover.presentPopoverFromRect(popRect, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Up, animated: true);
        }else{
            self.presentViewController(imagePicker, animated: true, completion: nil);
        }
    });

Solution 4 - Objective C

I ran into this after calling UIImagePickerController presentViewController: from the callback to a UIAlertView delegate. I solved the issue by pushing the presentViewController: call off the current execution trace using dispatch_async.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
        imagePickerController.delegate = self;
        
        if (buttonIndex == 1)
            imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        else
            imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
        
        [self presentViewController: imagePickerController
                           animated: YES
                         completion: nil];
    });
}

Solution 5 - Objective C

I had this issue when animating some views and the app would go into background mode and come back. I handled it by setting a flag isActive. I set it to NO in

- (void)applicationWillResignActive:(UIApplication *)application

and YES in

- (void)applicationDidBecomeActive:(UIApplication *)application

and animate or not animate my views accordingly. Took care of the issue.

Solution 6 - Objective C

I had this with an UIAlertControllerStyleActionSheet giving the user the option to take a photo with the camera or use one from library.

I tried a symbolic breakpoint on the error message enter image description here

That showed me the error is produced by the intern use of a UICollectionView during presentation

[self presentViewController:alert animated:YES completion:nil];

enter image description here

I fixed this by explixitly setting the frame before presenting

[alert setPreferredContentSize: alert.view.frame.size];

Here is the complete methode that is working without the error

-(void)showImageSourceAlertFromSender:(id)sender{
UIButton *senderButton = (UIButton*)sender;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:@"Camera" style:UIAlertActionStyleDefault
                                                     handler:^(UIAlertAction *action) {
                                                         [self takePhoto];
                                                     }];
UIAlertAction *libraryAction = [UIAlertAction actionWithTitle:@"Library" style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
                                                          [self selectPhotoFromLibraryFromSender:sender];
                                                      }];
[alert addAction:cameraAction];
[alert addAction:libraryAction];
alert.popoverPresentationController.delegate = self;
alert.popoverPresentationController.sourceRect = senderButton.frame;
alert.popoverPresentationController.sourceView = self.view;

[alert setPreferredContentSize: alert.view.frame.size];

[self presentViewController:alert animated:YES completion:^(){
}];}

Solution 7 - Objective C

You can silence the "Snapshotting a view" warning by referencing the view property before presenting the view controller. Doing so causes the view to load and allows iOS render it before taking the snapshot.

UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.popoverPresentationController.barButtonItem = (UIBarButtonItem *)sender;

... setup the UIAlertController ... 

[controller view]; // <--- Add to silence the warning.

[self presentViewController:controller animated:YES completion:nil];

Solution 8 - Objective C

For anyone that is seeing an issue with a black preview after image capture, hiding the status bar after the UIPickerController is shown seems to fix the issue.

UIImagePickerControllerSourceType source = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypeSavedPhotosAlbum;
UIImagePickerController *cameraController = [[UIImagePickerController alloc] init];
		cameraController.delegate = self;
		cameraController.sourceType = source;
		cameraController.allowsEditing = YES;
		[self presentViewController:cameraController animated:YES completion:^{
            //iOS 8 bug.  the status bar will sometimes not be hidden after the camera is displayed, which causes the preview after an image is captured to be black
            if (source == UIImagePickerControllerSourceTypeCamera) {
                [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
            }
        }];

Solution 9 - Objective C

I found the same issue and tried everything. I have two different apps, one in objective-C and one in swift - both have the same problem. The error message comes in the debugger and the screen goes black after the first photo. This only happens in iOS >= 8.0, obviously it is a bug.

I found a difficult workaround. Shut off the camera controls with imagePicker.showsCameraControls = false and create your own overlayView that has the missing buttons. There are various tutorials around how to do this. The strange error message stays, but at least the screen doesn't go black and you have a working app.

Solution 10 - Objective C

This might be a bug of built-in ImagePickerController. My code is working, but occasionally crashes on iPhone 6 Plus.

I've tried all solutions suggested by other answers but there were no luck. Problem finally solved after switching to JPSImagePickerController.

Solution 11 - Objective C

I've tried everything, my problem was that the image picker for the camera and photo library disappeared right after they showed. I solved it with the following line (swift)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

Solution 12 - Objective C

I'm pretty sure this is just a bug in iOS 8.0. It's reproducible with the simplest of POC apps that does nothing more than attempt to present a UIImagePickerController like you're doing above. Furthermore, there's no alternative pattern to displaying the image picker/camera, to my knowledge. You can even download Apple's Using UIImagePickerController sample app, run it, and it will generate the same error out of the box.

That said, the functionality still works for me. Other than the warning/error, do you have issues with the functioning of your app?

Solution 13 - Objective C

If we are using the UIImagePickerController as a property, then this warning will disappear. [tag:Xcode] assume that we are not using the result from the UIImagePickerController , if we are instantiating the UIImagePickerController within a function.

Solution 14 - Objective C

Calling this method worked for me. Place it after presenting your view.

[yourViewBeingPresented.view layoutIfNeeded];

Solution 15 - Objective C

I also encounter the same problem and I resolved it by checking if the camera is available:

BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];

Solution 16 - Objective C

I have came across with this issue. When we call the camera and release the views produced this issue. For an example call an camera and set view nil in viewDidDisappear method this error will come since there is not callback for camera event. Make sure about this case too for this error.

Solution 17 - Objective C

I got the same bug,getting bellow message in console while opening camera.

'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.'

For me problem was with the Bundle display name in Info.plist file.it was empty some how,i put my app name there and now it working fine.i did't received any camera permission alert because of empty Bundle display name.it blocked the view from rendering.

the problem was't with view but by presenting it without a permission.you can check it on settings-->privacy-->Camera,if your app not listed there problem might be same.

Solution 18 - Objective C

I'm using Phonegap, but this thread keeps coming as the first one when Googling about the error message.

For me this issue went away by defining the imagetype to PNG.

encodingType : Camera.EncodingType.PNG

So the whole line being:

 navigator.camera.getPicture(successFunction, failFunction, { encodingType : Camera.EncodingType.PNG, correctOrientation:true, sourceType : Camera.PictureSourceType    .PHOTOLIBRARY, quality: 70, allowEdit : false , destinationType: Camera.DestinationType.DATA_URL});

Your mileage may vary, but that did the trick for me.

Solution 19 - Objective C

Alternatively, consider using drawViewHierarchyInRect:

Swift:

extension UIImage{

    class func renderUIViewToImage(viewToBeRendered: UIView) -> UIImage
    {
        UIGraphicsBeginImageContextWithOptions(viewToBeRendered.bounds.size, true, 0.0)
        viewToBeRendered.drawViewHierarchyInRect(viewToBeRendered.bounds, afterScreenUpdates: true)
        viewToBeRendered.layer.renderInContext(UIGraphicsGetCurrentContext()!)

        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return finalImage
    }
}

Objective-C:

- (UIImage *)snapshot:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

Also see:

Solution 20 - Objective C

In my case ( XCode 7 and iOS 9 ), I use UINavigationController "hidden", so Ihave to add UINavigationControllerDelegate to present camera or roll and it work like it is supposed to! And pickerControllerDelegate.self doesn't display error either!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsouvickcseView Question on Stackoverflow
Solution 1 - Objective CKevinHView Answer on Stackoverflow
Solution 2 - Objective CPantelis ProiosView Answer on Stackoverflow
Solution 3 - Objective CdlwView Answer on Stackoverflow
Solution 4 - Objective CgregView Answer on Stackoverflow
Solution 5 - Objective CbyedissidentView Answer on Stackoverflow
Solution 6 - Objective CYedyView Answer on Stackoverflow
Solution 7 - Objective CSteve ShepardView Answer on Stackoverflow
Solution 8 - Objective CDanView Answer on Stackoverflow
Solution 9 - Objective CtzerView Answer on Stackoverflow
Solution 10 - Objective CJonSlowCNView Answer on Stackoverflow
Solution 11 - Objective CWaffelnView Answer on Stackoverflow
Solution 12 - Objective CGaurav PatelView Answer on Stackoverflow
Solution 13 - Objective CAntony OusephView Answer on Stackoverflow
Solution 14 - Objective CBobbyView Answer on Stackoverflow
Solution 15 - Objective CAFTAB MUHAMMED KHANView Answer on Stackoverflow
Solution 16 - Objective CGobi MView Answer on Stackoverflow
Solution 17 - Objective CShabeer AliView Answer on Stackoverflow
Solution 18 - Objective CJannunenView Answer on Stackoverflow
Solution 19 - Objective CEricView Answer on Stackoverflow
Solution 20 - Objective CDaniel Arantes LoverdeView Answer on Stackoverflow