iOS 7 UIImagePicker 预览黑屏问题

26
当我尝试从我的代码中加载相机时,相机预览是黑色的。如果我等待10-20秒钟,它将显示真实的相机预览。我找到了几个问题,其中一些建议在后台运行某些其他代码应该是造成这种情况的原因。然而,我没有任何在后台运行的代码。我应该怎么解决这个问题?
这是我运行相机的代码。
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];

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

10
欢迎来到 iOS 7 的 UIImagePicker 败笔。出现黑色预览屏幕的情况并没有明显的原因,有时候(往往如此),它会消失一段时间然后显示相机预览界面,但有时候不会。需要注意的是,完全相同的代码在 iOS 6 上可以无缝运行。我已经花了数小时尝试解决这个问题。这个问题值得我们认真对待!它让我们开发者看起来好像不知道如何编程,而实际上完全是苹果公司应该负责的事情。我正在考虑使用更低级别的API编写自己的图像捕获工具。 - daveMac
还有一件事,如果你在屏幕黑屏的时候拍照,照片仍然可以正常显示,所以这只是预览问题。 - daveMac
2
是的,当我拍照时它显示得很好。我还尝试了实现AVFoundation相机,但它也需要10-20秒才能显示预览。我无法相信这个问题没有解决方案。 - user2689024
检查我的答案:预览运行在主线程上,因此很容易崩溃。你必须实现一个信号量来锁定共享访问或等待苹果修复它。 - davbryn
也许使用completion:nil而不是NULL更好。我不知道是否有区别,但我从未在完成块中使用或见过NULL。 - Jonathan Gurebo
显示剩余7条评论
3个回答

21

大约5个月前,我的团队在iOS7中发现了UIImageViewController的内存泄漏问题。每次实例化都会使应用程序的速度呈指数级下降(即第一个alloc-init操作需要1秒延迟,第二个需要2秒延迟,第三个需要5秒延迟)。最终,我们遇到了30-60次延迟(就像你正在经历的情况一样)。

我们通过对UIImagePickerController进行子类化并将其变为单例来解决了这个问题。这样它只会被初始化一次。现在我们的延迟很小,而且我们避免了泄漏。如果子类化不是一个选项,请在您的viewController中尝试使用类属性,并像这样进行懒加载。

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

那么您以后只需调用它就可以了,例如:

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

1
感谢@eckyzero的回答。我有一种感觉,它减少了我等待黑屏消失的时间,但问题还没有完全解决。看起来你的代码让它更加响应。 - user2689024
这不是一个完整的修复,但肯定有所帮助。——苹果把这个问题放在他们下一个iOS 7更新的修复列表的最顶端,似乎并不过分要求。让应用程序的关键功能快速高效地工作非常重要!此外,在iOS 7中UIImagePickerController还存在其他错误。 - daveMac
我很高兴能够帮上一点忙,我完全同意你的看法。你知道是否有人向苹果报告了这个错误吗? - ebandersen

2

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

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


在这个视图中,我正在使用UICollectionView,并且我也在调整图像大小。我已经检查过了,我的UIImagePicker代码正在主线程上运行。你有什么想法吗?可能调整图像大小出了问题吗? - user2689024
我正在寻找解决方案 - 目前似乎是一个内部错误。我似乎无法在另一个线程上调整图像大小或同时使用AVAssetWriter:非常令人恼火。 - davbryn
我遇到了类似的问题(由于内存问题而关闭),但只有在调整捕获的图像大小时才会出现。这对我意味着什么?这里不进行图像调整大小吗? - swalkner

-1

这应该适用于您:

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

1
我也解决了这个问题。我遇到了后台线程的问题。上传图片任务我将其放在了后台线程中,现在我将其放回主线程中,它正常工作了。 - Nirav Jain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接