UIImagePickerController 错误:对尚未渲染的视图进行快照会导致 iOS 7 中的快照为空
Posted
技术标签:
【中文标题】UIImagePickerController 错误:对尚未渲染的视图进行快照会导致 iOS 7 中的快照为空【英文标题】:UIImagePickerController error: Snapshotting a view that has not been rendered results in an empty snapshot in iOS 7 【发布时间】:2013-09-24 06:17:03 【问题描述】:我只在 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 中。
有人知道吗?
【问题讨论】:
我也有同样的问题。在 iOS7 上 UIIMagePickerController 不再工作了。 调用这个方法对我有用。在呈现您的视图后放置它。 [yourViewBeingPresented.view layoutIfNeeded]; 【参考方案1】:iOS7 中的问题与过渡有关。似乎如果之前的转换没有完成并且您启动了一个新的转换,iOS7 会扰乱视图,而 iOS6 似乎可以正确管理它。
您应该在您的 UIViewController
中初始化您的相机,只有在视图加载并超时后:
- (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];
【讨论】:
到目前为止这似乎有效,我已经通过一张接一张地拍摄了 10 张照片来测试它,没有问题。 presentModalViewController 在 iOS 6 中已被弃用。建议现在使用 presentViewController。 iOS8 的同样的问题和修复。 我正在尝试通过 UIAertControl 进行这项工作 - 一个选项是为照片浏览器呈现图像选择器 - 这很好用,另一个是为相机呈现 - 这不是 .where使用 UIALertController 时会产生延迟吗? 我没有在 viewDidAppear/Load 中初始化相机。我有一个 tableview,我调出相机以响应其中一个 tableview 选择。我收到此错误消息。有什么想法吗?【参考方案2】:Apple 的 PhotoPicker 示例代码项目也出现了这个错误。
我在 iPhone 4 上使用 Xcode 5.0 和 iOS 7.0.3。
复制步骤:
在以下位置下载 Apple 的 PhotoPicker 示例项目 https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html
在 APLViewController.m 中注释掉第 125 行
//imagePickerController.showsCameraControls = NO;
在 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;
构建并启动应用程序。
启动后,将设备旋转到横向模式。
点击相机图标,以相机模式打开 UIImagePickerController。
查看控制台输出。
控制台输出
PhotoPicker[240:60b] 对尚未渲染的视图进行快照会导致快照为空。确保您的视图在快照之前或屏幕更新后的快照之前至少渲染过一次。
showsCameraControls 属性
当它的值为 YES(默认值)时,我会遇到问题。
将此设置为 NO 会消除该消息。
错误报告
我刚刚向 Apple 提交了错误报告。
我尝试了许多在不同帖子中提出的建议,但没有找到令人满意的解决方法。
【讨论】:
苹果是如何回复你的?我有同样的问题,*** 中的解决方案不起作用。 我还没有收到 Apple 的消息。如果我收到他们的回复,我会发布回复。 有来自苹果的消息吗? @斯科特卡特 刚刚再次检查。自 2013 年 11 月 2 日提交以来,未对未解决的错误采取任何行动。 这是 bugreport.apple.com 上的错误 15377241【参考方案3】:当我尝试在弹出框内显示相机视图时遇到问题。在 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.
也是。
但是,在我按照Taking Pictures and Movies, iOS Developer Library 中的描述将相机视图的呈现方式更改为全屏之后,一切都恢复正常,并且消息再也没有出现过。但是,我必须确保根据应用程序所处的模式(即显示相机视图或照片卷),每当调用 - (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker
方法时,我都必须关闭弹出框或视图控制器。
【讨论】:
cameraUI.modalPresentationStyle = UIModalPresentationFullScreen;为我工作。这是这里唯一成功的事情。谢谢! 终于!我已经多次遇到这个问题,但从未找到一个好的解决方案。现在感觉很愚蠢,因为永远不会在问题线程中往下看 - imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;为我解决了这个问题。这应该是公认的答案:)【参考方案4】:创建属性
@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];
这应该可以解决问题
【讨论】:
picker.modalPresentationStyle = UIModalPresentationCurrentContext;改变了我。 它在第一次出现选择器时工作,但之后警告返回。 我确认 picker.modalPresentationStyle = UIModalPresentationCurrentContext;为我解决了 iOS 8 中布局错误的问题 不适合我——将此添加到 iOS 8.1.3 上的 UIButton 操作中 这看起来很有希望,但对我的快照问题没有任何帮助,并且在拍摄照片后在图像的一部分周围显示了一个无用的框架。【参考方案5】:我用这段代码解决了这个问题:
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];
【讨论】:
虽然这个想法在理论上可行,但不幸的是,显示的控件不起作用或显示正确。 而且它也没有消除警告(至少对我来说)【参考方案6】:我有同样的问题并找到了解决办法。我认为,该错误与您的应用程序的方向有关。我的应用程序只使用横向模式,但 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创建一个类别,(iOS6中支持的InterfaceOrientations从UIViewController移动到UINavigationController):
@implementation UINavigationController (RotationIOS6)
- (NSUInteger)supportedInterfaceOrientations
return UIInterfaceOrientationMaskLandscape;
@end
此解决方案可在 iOS 6.0、6.1、7.0 上正常运行。希望这会有所帮助。
【讨论】:
我正在修复一个纵向模式应用程序,它会给出 OP 中提到的错误。因此,您的解决方案似乎并不普遍适用。 您是否尝试将 try-catch 块添加到 main.m 并打印异常和堆栈跟踪? 喜欢this? @JohnK 是的,就像这样。【参考方案7】:我在使用 iOS SDK 6.1 构建应用程序、部署目标 iOS 6.1 并在支持 iOS 7 的 iPhone 上运行应用程序时收到此错误。应用程序不会崩溃,但实现 UIViewController shouldAutorotate
方法可以帮助我删除错误消息。
- (BOOL)shouldAutorotate
return YES;
【讨论】:
【参考方案8】:我在尝试修改 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];
然后错误消失,应用程序正常工作!
【讨论】:
【参考方案9】:试试这个,使用
[self performSelector:@selector(presentCameraView) withObject:nil afterDelay:1.0f];
和功能
-(void)presentCameraView
[self presentViewController:imagePicker animated:YES completion:nil];
替换。 [self presentModalViewController:imagePicker animated:YES];
并且将imagePicker
设为全局变量。
【讨论】:
【参考方案10】:这就是在我的应用程序上为我解决的问题,ymmv
首先是一个 iPhone - iPad 应用程序
在 appname-Info.plist 中。在 Supported interface orientations(iPad) 中显示了 4 个方向。
在支持的界面方向中显示了 3 个方向。我添加了第四个并运行了应用程序,没有调试输出。
希望这会有所帮助。
【讨论】:
【参考方案11】:我刚刚遇到了同样的问题。就我而言,问题是我有一些非 ARC 代码,并且我已将其迁移到 ARC。当我进行迁移时,我没有强烈引用UIImagePickerController
,这就是崩溃的原因。
希望对你有帮助:)
【讨论】:
【参考方案12】:我在 iOS 8 中遇到了同样的问题,但是在我的应用程序的设置-->隐私中禁用了相机访问。刚刚启用它,它正在工作。
【讨论】:
【参考方案13】:我花了很长时间试图找到解决方案,结果令人惊讶的是我最终找到了它,并且一旦我发现它就非常有趣。
您将执行以下操作来检索您选择的图像并恢复工作:)
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
UIImage* pickedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
[composeImageView setImage:pickedImage];
[picker dismissViewControllerAnimated:YES completion:nil];
是的,要解决此问题,您只需要正常关闭选择器,因为似乎出现以下消息:“对未渲染的视图进行快照会导致快照为空。确保您的视图在快照之前至少已渲染一次或屏幕更新后的快照。”停止选择器响应,但您可以将其关闭并正常检索图像。
【讨论】:
【参考方案14】:在我的例子中,它与布局更改有关:显示 UIImagePickerViewController
的 VC 隐藏了状态栏,但 UIImagePickerViewController
没有。
所以,我解决了它在UIImagePickerViewController
中隐藏状态栏的问题,如answer 所示。
【讨论】:
【参考方案15】:没有直接回答您的问题,但您提到您有内存警告,您可能将原始图像存储在可能导致内存警告的属性中。这是因为原始图像占用了大约 30MB 的内存。在 iPhone 4 系列的 iOS6 上测试应用程序时,我注意到类似的内存警告。当设备升级到 iOS7 时,我仍然收到此警告。在 iOS7 上测试 iPhone 5 系列时没有内存警告。
【讨论】:
【参考方案16】:变化
[self presentViewController:imagePicker animated:YES completion:nil];
到
[self presentViewController:imagePicker animated:YES completion:NULL];
为我解决了这个问题。
【讨论】:
以上是关于UIImagePickerController 错误:对尚未渲染的视图进行快照会导致 iOS 7 中的快照为空的主要内容,如果未能解决你的问题,请参考以下文章
UIImagePickerController、自定义 UIButton 和 AutoLayout
OCMock 模拟 UIImagePickerController