iOS 7 UIImagePicker 预览黑屏

Posted

技术标签:

【中文标题】iOS 7 UIImagePicker 预览黑屏【英文标题】:iOS 7 UIImagePicker preview black screen 【发布时间】:2014-02-19 17:49:49 【问题描述】:

当我尝试从我的代码中加载相机时,相机预览是黑色的。如果我等待 10-20 秒,它将显示真实的相机预览。我发现了几个问题,其中一些建议在后台运行一些其他代码应该是原因。但是我没有在后台运行任何代码。 我应该如何解决这个问题?

这是我运行相机的代码

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

photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:photoPicker animated:YES completion:NULL];

【问题讨论】:

这段代码看起来不错——我建议试试这个:dispatch_async(dispatch_get_main_queue(), ^ <your current code here> ); 看看是否有任何变化。如果它工作正常,这意味着您正在在后台运行代码某处 您还可以在您发布的任何行上设置断点,并在您点击断点时查看 Xcode 侧边栏以查看您所在的线程。 @Undo 我试过你的代码,没有任何改变。 欢迎来到 ios 7 的 UIImagePicker。绝对没有明显的原因,有时(通常)你会得到一个黑色的预览屏幕。有时它会在一段时间后消失,并且您会获得相机预览,有时则不会。请注意,完全相同的代码可以在 iOS 6 上无缝运行。我花了几个小时试图弄清楚这一点。这个问题值得认真关注!它让我们的开发人员看起来像我们不知道如何编程,而它完全掌握在 Apple 手中。我正在考虑使用较低级别的 API 编写自己的图像捕获。 是的,当我拍照时它显示得很好。我也尝试过实现 AVFoundation 相机,它还需要 10-20 秒才能显示预览。我不敢相信这个问题没有解决方案。 【参考方案1】:

大约 5 个月前,我的团队在 iOS7 中发现了 UIImageViewController 的内存泄漏。每次实例化都会以指数方式减慢应用程序的速度(即第一个 alloc-init 有 1 秒延迟,第二个有 2 秒延迟,第三个有 5 秒延迟)。最终,我们有 30-60 次延迟(与您遇到的情况相似)。

我们通过子类化 UIImagePickerController 并将其设为 Singleton 解决了该问题。这样,它只被初始化一次。现在我们的延迟是最小的,我们避免了泄漏。如果子类化不是一个选项,请在 viewController 中尝试一个类属性,然后像这样延迟加载它。

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

然后你可以稍后调用它:

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

【讨论】:

感谢@eckyzero 的回答。我有一种感觉,它减少了我必须等待黑屏删除的时间,但还没有完全解决。似乎它对您的代码的响应速度更快 这不是一个完整的修复程序,但它肯定会有所帮助。 ——要求 Apple 将此问题置于 iOS 7 下一次更新的修复列表的最顶端并不过分。让应用程序的这些关键功能快速有效地运行非常重要!此外,这不是 iOS 7 中 UIImagePickerController 的唯一错误。 我很高兴能帮上一点忙,我完全同意你的看法。您知道是否有人向 Apple 提交了错误?【参考方案2】:

我自己也遇到过这种情况 - 如果主调度线程上正在运行某些东西,就会发生这种情况 - 您是否正在调整图像大小?

它将预览放到主线程上,如果有东西在使用它,你会得到一个黑屏。这是一个错误,解决方法是接管主线程或禁用照片选择器,直到队列空闲

【讨论】:

在这个视图中,我正在使用 UICollectionView,是的,我也在调整图像大小。我已经检查并且我的 UIImagePicker 代码正在主线程上运行。你有什么想法可能是调整图像大小有问题吗? 我自己也在寻找解决方案 - 目前看来这是一个内部错误。我似乎无法在另一个线程上调整图像大小或同时使用 AVAssetWriter:非常烦人 我遇到了类似的问题(由于内存问题而关闭),但前提是我调整了捕获的图像的大小。这对我意味着什么?这里没有调整图片大小?【参考方案3】:

这应该适合你:

    - (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;

【讨论】:

我也解决了问题。我遇到了后台线程问题。上传图像任务我把它放在后台线程中。我把它放回主线程并正常工作。

以上是关于iOS 7 UIImagePicker 预览黑屏的主要内容,如果未能解决你的问题,请参考以下文章

如何模态呈现一个视图来选择 UIImagePicker sourceType?

在 iOS8 上使用 UIImagePicker 结果 URL 和 PHAsset 从“我的照片流”加载图像

在 iOS 中存储 UIImagePicker 选取的图像

ios 7 drawViewHierarchyInRect:afterScreenUpdates:仅在 iPad 上出现黑屏

如何在 iOS 的某些文件输入字段上获取 UIWebView 中 UIImagePicker 选择的图像?

MPMoviePlayerController 在 iOS 7 中显示带声音的黑屏,在 iOS 6 中运行良好