UIImagePickerController错误:对尚未渲染的视图进行快照会导致iOS 7中的快照为空


103

我仅在iOS 7中收到此错误,并且应用程序崩溃了。在iOS 6中,打开相机时,我从未收到任何错误,只有一次内存警告。

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.

这是我在做什么。

imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setDelegate:self];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setAllowsEditing:YES];

[self presentModalViewController:imagePicker animated:YES];

我确实尝试过延迟presentModalViewController,但仍然收到相同的消息。几秒钟后(7-10),应用程序崩溃了。

此错误仅在iOS 7中出现。

有人知道吗?


3
我也有同样的问题。在iOS7上,UIIMagePickerController不再起作用。
2013年

调用此方法对我有用。提出您的看法后将其放置。[yourViewBeingPresented.view layoutIfNeeded];
鲍比

Answers:


32

iOS7中的问题与过渡有关。看来,如果上一个过渡未完成,而您启动了一个新过渡,则iOS7会弄乱视图,而iOS6似乎可以正确地对其进行管理。

UIViewController只有在加载视图并超时后,才应在中初始化Camera :

- (void)viewDidAppear:(BOOL)animated 
{
    [super viewDidAppear:animated];
    //show camera...
    if (!hasLoadedCamera)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];
}

这是初始化代码

- (void)showcamera {
    imagePicker = [[UIImagePickerController alloc] init];
    [imagePicker setDelegate:self];
    [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    [imagePicker setAllowsEditing:YES];

    [self presentModalViewController:imagePicker animated:YES];
}

1
到目前为止,这似乎仍然有效,我已经通过连续拍摄10张图片来进行测试,没有问题。
DevC

3
在iOS 6中不推荐使用presentModalViewController。建议现在使用presentViewController。
加里蒙2014年

5
同样的麻烦和修复iOS8。
Yauheni Shauchenka 2014年

1
我正在尝试通过UIAertControl进行这项工作-一个选项是为照片浏览器提供图像选择器-可以正常工作,另一个选择为摄像头提供-这不是。我在使用时会在延迟中建立哪里UIALertController?
SimonTheDiver 2015年

3
我没有在viewDidAppear / Load中初始化相机。我有一个表格视图,并根据该表格视图选项之一打开相机。我收到此错误消息。有任何想法吗?
亨宁2015年

18

苹果的PhotoPicker示例代码项目也为我显示了此错误。

我在iPhone 4上使用Xcode版本5.0和iOS 7.0.3。

重现步骤:

  1. https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html下载Apple的PhotoPicker示例项目

  2. 在APLViewController.m中注释掉第125行

    //imagePickerController.showsCameraControls = NO;

  3. 在APLViewController.m中注释掉第130-133行

    //[[NSBundle mainBundle] loadNibNamed:@"OverlayView" owner:self options:nil];
    // self.overlayView.frame = imagePickerController.cameraOverlayView.frame;
    // imagePickerController.cameraOverlayView = self.overlayView;
    // self.overlayView = nil;

  4. 生成并启动该应用程序。

  5. 启动后,将设备旋转到横向模式。

  6. 单击“相机”图标以“相机”模式打开UIImagePickerController。

  7. 查看控制台输出。

控制台输出

PhotoPicker [240:60b]快照未渲染的视图将导致快照为空。确保在快照前或屏幕更新后快照至少已渲染一次视图。

showsCameraControls属性

当它的值为YES(默认值)时,对我来说就会出现问题。

将此设置为“否”将消除该消息。

错误报告

我刚刚向Apple提交了错误报告。

我已经尝试了在不同帖子中提出的许多建议,但没有找到令人满意的解决方法。


1
苹果如何回答您?我有同样的问题,stackoverflow中的解决方案不起作用。
heekyu 2014年

我还没有收到苹果的消息。如果收到他们的回复,我会发表回复。
Scott Carter

苹果有什么消息吗?@ScottCarter
本杰明·图格2014年

1
刚刚再次检查。自公开漏洞于2013
Scott Carter

这是bugreport.apple.com上的错误15377241
Scott Carter

11

当我尝试在弹出框内显示摄像机视图时遇到了问题。在iOS6下这没问题,但是在iOS7中我收到消息

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.

也一样

但是,按照“拍照和电影”中的描述,我将相机视图的显示方式更改为全屏显示后,iOS开发人员库一切恢复正常,消息再也没有出现。但是,我必须确保根据应用程序所处的模式(即显示相机视图或照片胶卷),无论何时- (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker调用该方法,我都必须关闭弹出窗口或视图控制器。


3
cameraUI.modalPresentationStyle = UIModalPresentationFullScreen; 为我工作。这是唯一成功的方法。谢谢!
daveMac

2
最后!我曾多次遇到此问题,却从未找到好的解决方案。现在就变得如此愚蠢,因为从未在问题线程中深入探讨-imagePicker.modalPresentationStyle = UIModalPresentationFullScreen; 为我解决了这个问题。这应该是公认的答案:)
woobione 2014年

6

创建一个属性

@property (nonatomic) UIImagePickerController *imagePickerController;

然后

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.modalPresentationStyle = UIModalPresentationCurrentContext;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing = YES;
self.imagePickerController = picker;
[self presentViewController:self.imagePickerController animated:YES completion:nil];

这应该解决问题


3
picker.modalPresentationStyle = UIModalPresentationCurrentContext; 为我带来了不同。
伯纳先生2013年

1
它在第一次显示选择器时有效,但之后又返回警告。
daveMac 2014年

我确认picker.modalPresentationStyle = UIModalPresentationCurrentContext; 解决了我错了布局在iOS 8的问题
若奥·努涅斯

不适合我-在iOS 8.1.3上的UIButton操作中添加了此功能
Andy

这似乎很有希望,但是对于快照问题并没有帮助我,并且在拍摄照片后在图像的一部分周围显示了无用的帧。
提请。.

4

我使用此代码来解决此问题:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [imagePicker setShowsCameraControls:NO];
    [self presentViewController:imagePicker animated:YES completion:^{
        [imagePicker setShowsCameraControls:YES];
    }];
} else {
    [imagePicker setShowsCameraControls:YES];
    [self presentModalViewController:imagePicker animated:YES];
}

1
尽管该想法在理论上可行,但不幸的是,所示控件无法正常工作或无法正确显示。
daveMac 2014年

而且它也没有摆脱警告(至少对我而言)
Ege Akpinar 2014年

3

我有同样的问题,找到了解决方法。我认为,该错误与应用程序的方向有关。我的应用程序仅使用横向模式,而UIImagePickerController使用纵向模式。我将try-catch块添加到main.m中,并得到真正的异常:

Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES

我如何解决这个问题:

1)在Target-> General或.plist文件中重新检查设备方向:支持的界面方向:横向左,横向右。

2)添加AppDelegate.m:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait;
}

完成此步骤后,UIImagePickerController可以正常工作,但是我的视图控制器可以旋转到纵向模式。因此,要解决此问题:

3)为UINavigationController创建一个类别,(supportedInterfaceOrientations从iOS6中的UIViewController移到了UINavigationController):

@implementation UINavigationController (RotationIOS6)

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

@end

此解决方案可在iOS 6.0、6.1、7.0上正常运行。希望这可以帮助。


1
我正在修复一个纵向模式应用程序,该应用程序给出了OP中提到的错误。因此,您的解决方案似乎并不普遍适用。
约翰·K

您是否尝试将try-catch块添加到main.m并打印异常和stacktrace?
Roman Ermolov 2013年


@JohnK是的,像这样。
Roman Ermolov 2013年

3

使用iOS SDK 6.1构建应用程序,部署目标iOS 6.1并在支持iOS 7的iPhone上运行应用程序时出现此错误。应用程序不会崩溃,但是实现UIViewController shouldAutorotate方法可以帮助我删除错误消息。

- (BOOL)shouldAutorotate {
    return YES;
}

3

当我尝试修改Avirary SDK随附的演示应用程序时遇到了相同的问题,在演示应用程序中,它只能编辑从相机胶卷中拾取的照片。为了尝试通过从相机捕获来编辑照片,我首先在UIViewcontroller.m文件中添加了以下代码:

#pragma mark - Take Picture from Camera
- (void)showCamera
{
//[self launchPhotoEditorWithImage:sampleImage highResolutionImage:nil];

    if ([self hasValidAPIKey]) {
        UIImagePickerController * imagePicker = [UIImagePickerController new];
        [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
        [imagePicker setDelegate:self];
        [imagePicker setAllowsEditing:YES]; //important, must have

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
            [self presentViewController:imagePicker animated:YES completion:nil];
        }else{
            [self presentViewControllerInPopover:imagePicker];
        }
    }
}

然后,当我运行该应用程序时,发生了错误:

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.

要解决该错误,请如下所示修改UIViewContooler.m文件中的UIImagePicker委托:

#pragma mark - UIImagePicker Delegate

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSURL * assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];

    void(^completion)(void)  = ^(void){

        [[self assetLibrary] assetForURL:assetURL resultBlock:^(ALAsset *asset) {
            if (asset){
                [self launchEditorWithAsset:asset];
            }
        } failureBlock:^(NSError *error) {
            [[[UIAlertView alloc] initWithTitle:@"Error" message:@"Please enable access to your device's photos." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
        }];

        UIImage * editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
        if(editedImage){
            [self launchPhotoEditorWithImage:editedImage highResolutionImage:editedImage];
        }

    };

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self dismissViewControllerAnimated:YES completion:completion];
    }else{
        [self dismissPopoverWithCompletion:completion];
    }

}    

然后错误消失了,该应用程序开始运行!


1

试试这个,用

[self performSelector:@selector(presentCameraView) withObject:nil afterDelay:1.0f];

和功能

-(void)presentCameraView{
    [self presentViewController:imagePicker animated:YES completion:nil];
}

取代。[self presentModalViewController:imagePicker animated:YES]; 和因果关系imagePicker作为全局变量。


1

这就是在我的应用ymmv上为我修复的问题

首先是iPhone-iPad应用程序

在appname-Info.plist中。在支持的界面方向(iPad)中显示了4个方向。

在支持的界面方向上显示了3个方向。我添加了第四个并运行了该应用程序,没有调试输出。

希望这可以帮助。


0

我刚刚遇到了同样的问题。就我而言,问题是我有一些非ARC代码,并且已将其迁移到ARC。进行迁移时,我并没有强烈地参考UIImagePickerController,这就是崩溃的原因。

希望能帮助到你 :)


0

我在iOS 8中遇到了同样的问题,但是在我的应用程序的“设置”->“隐私”中禁用了“相机访问。刚刚启用它,它正在工作。


0

我花了很长时间尝试找到解决方案,但是令人惊讶的是我终于找到了解决方案,一旦发现它就很有趣。

这是您将要检索的图像并恢复工作的方法:)

-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
    UIImage* pickedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    [composeImageView setImage:pickedImage];
[picker dismissViewControllerAnimated:YES completion:nil];
 }

是的,要解决该问题,您只需要正常关闭选择器,就像出现以下消息一样:“快照未渲染的视图会导致生成一个空快照。确保在快照之前至少渲染了一次视图或在快照之后至少对快照进行了渲染屏幕更新。” 停止选择器做出响应,但是您可以将其关闭并正常检索图像。


0

就我而言,这与布局更改有关:呈现的VC UIImagePickerViewController隐藏了状态栏,但UIImagePickerViewController没有隐藏。

因此,我解决了它将状态栏隐藏UIImagePickerViewController在此答案所示的状态。


-1

不是直接回答您的问题,而是提到您有内存警告,您可能会将原始图像存储在可能导致内存警告的属性中。这是因为原始映像大约占用30MB的内存。在iPhone 4系列的iOS6上测试应用程序时,我注意到了类似的内存警告。当设备升级到iOS7时,我仍然收到此警告。在iOS7上的iPhone 5系列上进行测试时,没有内存警告。


-5

改变中

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

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

为我解决了这个问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.