iOS 8快照未呈现的视图会导致空快照

时间:2014-09-17 07:31:49

标签: objective-c ios8 uiimagepickercontroller

在iOS 8中,我遇到了从相机捕捉图像的问题,直到现在我正在使用此代码

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

但是在iOS 8中我得到了这个:

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.

我已尝试使用This Post提供的解决方案

@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];

和这个

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

和这个

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];
});

和这个

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

和这个

[self presentViewController:controller animated:YES completion:^{

}];

任何想法?

19 个答案:

答案 0 :(得分:131)

我很确定这只是iOS 8.0中的一个错误。使用最简单的POC应用程序可以重现它,除了尝试呈现像您在上面所做的那样UIImagePickerController之外。此外,据我所知,没有其他模式可以显示图像选择器/相机。你甚至可以下载Apple的Using UIImagePickerController sample app,运行它,它会立即生成相同的错误。

也就是说,功能仍然适用于我。除了警告/错误之外,您的应用程序运行是否存在问题?

答案 1 :(得分:45)

我在这个问题上挣扎了几个小时,我已经阅读了所有相关主题并发现错误是由于我的设备的隐私设置,我的应用程序的相机访问被阻止了!我从来没有拒绝访问相机,我不知道它是如何被阻止但这是问题!

答案 2 :(得分:33)

我没有足够的声望点来评论@ greg上面的答案,所以我会在这里添加我的观察。我有一个适用于iPad和iPhone的Swift项目。我的主视图控制器中有一个方法(下面的相关位)。当我在手机上测试时,一切正常,不会产生任何警告。当我在iPad上运行它时,一切正常但我看到关于快照视图的警告。然而,有趣的是,当我在没有使用弹出控制器的情况下在iPad上运行时,一切正常,没有任何警告。不幸的是,如果没有使用相机,Apple要求必须在iPad上的popover中使用图像选择器。

@RestController
@RequestMapping("/tasks")
public class TaskController {

@Autowired
private TaskRepository taskRepository;
.
.
.
@RequestMapping(value = "/setview/{id}", method = RequestMethod.GET)
public Iterable<Task> setView(@PathVariable Integer id) {
    System.out.println("setViewTrue  -------------------");
    Iterable<Task> tasks = taskRepository.findByUserId(id);

    for (Task t : tasks) {
        t.setView(true);
        taskRepository.save(t);
        System.out.println("task****: "+ t.isView());
    }
    return tasks;

    }
  }

答案 3 :(得分:16)

我在调用UIImagePickerController presentViewController之后遇到了这个问题:从回调到UIAlertView委托。我通过推送presentViewController解决了这个问题:使用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];
    });
}

答案 4 :(得分:12)

在动画一些视图时,我遇到了这个问题,应用程序将进入后台模式并返回。我通过设置标志isActive来处理它。

我把它设置为NO
- (void)applicationWillResignActive:(UIApplication *)application

中的YES
- (void)applicationDidBecomeActive:(UIApplication *)application

并相应地制作动画或不动画我的视图。关心这个问题。

答案 5 :(得分:11)

我有一个UIAlertControllerStyleActionSheet,让用户可以选择用相机拍照或使用库中的照片。

我在错误消息上尝试了一个符号断点 enter image description here

这表明我在演示期间实际使用了UICollectionView产生了错误

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

enter image description here

我通过在呈现

之前设置框架来解决这个问题
[alert setPreferredContentSize: alert.view.frame.size];

这是完整的没有错误的方法

-(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:^(){
}];}

答案 6 :(得分:10)

您可以在呈现视图控制器之前通过引用view属性来静音“快照视图”警告。这样做会导致视图加载,并允许iOS在拍摄快照之前渲染它。

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

答案 7 :(得分:8)

对于在图像捕获后看到黑色预览问题的任何人,在显示UIPickerController后隐藏状态栏似乎可以解决问题。

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

答案 8 :(得分:5)

我发现了同样的问题并尝试了一切。我有两个不同的应用程序,一个在Objective-C中,一个在swift中 - 两者都有相同的问题。调试器中出现错误消息,第一张照片后屏幕变黑。这只发生在iOS&gt; = 8.0,显然这是一个错误。

我发现了一个困难的解决方法。使用imagePicker.showsCameraControls = false关闭相机控件并创建自己的具有缺失按钮的overlayView。有关如何执行此操作的各种教程。 奇怪的错误信息仍然存在,但至少屏幕不会变黑并且你有一个正在运行的应用程序。

答案 9 :(得分:5)

这可能是内置ImagePickerController的错误。我的代码正在运行,但偶尔会在iPhone 6 Plus上崩溃。

我已尝试过其他答案提出的所有解决方案,但没有运气。切换到JPSImagePickerController后,问题终于解决了。

答案 10 :(得分:3)

我很确定这只是iOS 8.0中的一个错误。它可以用最简单的POC应用程序重现,它只是尝试呈现像你上面所做的那样的UIImagePickerController。此外,据我所知,没有其他模式可以显示图像选择器/相机。你甚至可以下载Apple的Using UIImagePickerController示例应用程序,运行它,它会立即生成相同的错误。

也就是说,功能仍然适用于我。除了警告/错误之外,您的应用程序运行是否存在问题?

答案 11 :(得分:3)

如果我们使用UIImagePickerController作为属性,则此警告将消失。如果我们在函数中实例化UIImagePickerController假设我们没有使用UIImagePickerController的结果。

答案 12 :(得分:2)

调用此方法对我有用。在展示您的视图后放置它。

[yourViewBeingPresented.view layoutIfNeeded];

答案 13 :(得分:1)

我遇到过这个问题。当我们调用相机并发布产生此问题的视图时。例如,在viewDidDisappear方法中调用摄像机并设置视图nil,因为没有摄像机事件的回调,所以会出现此错误。对于此错误,请确保此案例。

答案 14 :(得分:1)

我也遇到了同样的问题,我通过检查相机是否可用来解决它:

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

答案 15 :(得分:1)

我得到了同样的错误,在打开相机的同时在控制台中收到了轰鸣声。

&#39;快照未呈现的视图会导致空快照。确保您的视图在屏幕更新后的快照或快照之前至少呈现一次。&#39;

对我来说问题是Info.plist文件中的Bundle显示名称。它是空的,如何,我把我的应用程序名称放在那里,现在它工作正常。我没有收到任何相机权限警报,因为空Bundle display name.it阻止了视图的渲染。

问题不在于视图,而是在没有许可的情况下展示。您可以在设置上进行检查 - &gt;隐私 - &gt;相机,如果您的应用未列在那里问题可能相同。

答案 16 :(得分:1)

我使用的是Phonegap,但是当谷歌搜索错误信息时,这个帖子仍然是第一个。

对我来说,通过将图像类型定义为PNG,这个问题就消失了。

encodingType : Camera.EncodingType.PNG

所以整条线都是:

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

你的里程可能会有所不同,但这对我有用。

答案 17 :(得分:1)

或者,请考虑使用drawViewHierarchyInRect

<强>夫特:

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

<强>目标-C:

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

    return image;
}

另见:

答案 18 :(得分:0)

在我的情况下(XCode 7和iOS 9),我使用UINavigationController“隐藏”,所以我要添加UINavigationControllerDelegate来呈现相机或滚动,它应该像它应该的那样工作! And pickerControllerDelegate.self也不显示错误!