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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25884801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:26:29  来源:igfitidea点击:

iOS 8 Snapshotting a view that has not been rendered results in an empty snapshot

objective-cios8uiimagepickercontroller

提问by souvickcse

In iOS 8 I am having problem capturing images from camera till now I am using this code for

在 iOS 8 中,我在从相机捕获图像时遇到问题,直到现在我使用此代码

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

But in iOS 8 I am getting this:

但是在 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.

I have tried with the solution provided by This Postwith

我曾尝试与所提供的解决方案这个帖子

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

and this

和这个

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

and this

和这个

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

and this

和这个

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

and this

和这个

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

}];

any idea?

任何的想法?

回答by KevinH

I'm pretty sure this is just a bug in iOS 8.0. It's reproducible with the simplest of POC apps that does nothing more than attempt to present a UIImagePickerControllerlike you're doing above. Furthermore, there's no alternative pattern to displaying the image picker/camera, to my knowledge. You can even download Apple's Using UIImagePickerController sample app, run it, and it will generate the same error out of the box.

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

That said, the functionality still works for me. Other than the warning/error, do you have issues with the functioning of your app?

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

回答by Pantelis Proios

I was struggling with this issue for several hours, i have read every relevant topic and found out that the error was caused because under the privacy settings of my device, the camera access to my app was blocked!!! I have never denied access to camera and i don't know how it was blocked but that was the problem!

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

回答by dlw

I don't have enough reputation points to comment on @greg's answer above, so will add my observations here. I have a Swift project for both iPad and iPhone. I have a method inside my main view controller (relevant bit below). When I test this on a phone, everything works properly and no warnings are generated. When I run it on an iPad, everything works properly but I see the warning about snapshotting the view. The interesting bit, however, is that when I run on an iPad without using the popover controller, everything works properly with no warning. Unfortunately, Apple mandates that the image picker must be used within a popover on iPad, if the camera is not being used.

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

    dispatch_async(dispatch_get_main_queue(), {
        let imagePicker: UIImagePickerController = UIImagePickerController();
        imagePicker.sourceType = UIImagePickerControllerSourceType.SavedPhotosAlbum;
        imagePicker.mediaTypes = [kUTTypeImage];
        imagePicker.allowsEditing = false;
        imagePicker.delegate = self;

        if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){ // on a tablet, the image picker is supposed to be in a popover
            let popRect: CGRect = buttonRect;
            let popover: UIPopoverController = UIPopoverController(contentViewController: imagePicker);
            popover.presentPopoverFromRect(popRect, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Up, animated: true);
        }else{
            self.presentViewController(imagePicker, animated: true, completion: nil);
        }
    });

回答by greg

I ran into this after calling UIImagePickerController presentViewController: from the callback to a UIAlertView delegate. I solved the issue by pushing the presentViewController: call off the current execution trace using dispatch_async.

我在调用 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];
    });
}

回答by byedissident

I had this issue when animating some views and the app would go into background mode and come back. I handled it by setting a flag isActive. I set it to NO in

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

- (void)applicationWillResignActive:(UIApplication *)application

and YES in

是的

- (void)applicationDidBecomeActive:(UIApplication *)application

and animate or not animate my views accordingly. Took care of the issue.

并相应地动画或不动画我的观点。照顾了这个问题。

回答by Yedy

I had this with an UIAlertControllerStyleActionSheet giving the user the option to take a photo with the camera or use one from library.

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

I tried a symbolic breakpoint on the error message enter image description here

我在错误消息上尝试了一个符号断点 在此处输入图片说明

That showed me the error is produced by the intern use of a UICollectionView during presentation

这向我展示了错误是由演示期间 UICollectionView 的实习生使用产生的

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

enter image description here

在此处输入图片说明

I fixed this by explixitly setting the frame before presenting

我通过在呈现之前明确地设置框架来解决这个问题

[alert setPreferredContentSize: alert.view.frame.size];

Here is the complete methode that is working without the error

这是没有错误的完整方法

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

回答by Steve Shepard

You can silence the "Snapshotting a view" warning by referencing the viewproperty before presenting the view controller. Doing so causes the view to load and allows iOS render it before taking the snapshot.

您可以通过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];

回答by Dan

For anyone that is seeing an issue with a black preview after image capture, hiding the status bar after the UIPickerController is shown seems to fix the issue.

对于在图像捕获后看到黑色预览问题的任何人,在显示 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];
            }
        }];

回答by Thomas Zimmer

I found the same issue and tried everything. I have two different apps, one in objective-C and one in swift - both have the same problem. The error message comes in the debugger and the screen goes black after the first photo. This only happens in iOS >= 8.0, obviously it is a bug.

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

I found a difficult workaround. Shut off the camera controls with imagePicker.showsCameraControls = false and create your own overlayView that has the missing buttons. There are various tutorials around how to do this. The strange error message stays, but at least the screen doesn't go black and you have a working app.

我找到了一个困难的解决方法。使用 imagePicker.showsCameraControls = false 关闭相机控件并创建您自己的具有缺失按钮的 overlayView。有关于如何做到这一点的各种教程。奇怪的错误消息仍然存在,但至少屏幕不会变黑并且您有一个可以运行的应用程序。

回答by JonSlowCN

This might be a bug of built-in ImagePickerController. My code is working, but occasionally crashes on iPhone 6 Plus.

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

I've tried all solutions suggested by other answers but there were no luck. Problem finally solved after switching to JPSImagePickerController.

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