web-dev-qa-db-ja.com

iOS 8レンダリングされていないビューをスナップショットすると、スナップショットが空になります

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.

私は この投稿 で提供される解決策で試しました

@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:^{

}];

何か案が?

228
souvickcse

私はこれがiOS 8.0の単なるバグであると確信しています。それはあなたが上でやっているようにUIImagePickerControllerを提示することを試みること以上の何もしない最も単純なPOCアプリで再現可能です。さらに、私の知る限りでは、画像ピッカー/カメラを表示するための代替パターンはありません。あなたは、Appleの Using UIImagePickerControllerサンプルアプリ をダウンロードして実行することもでき、それは箱から出して同じエラーを生成します。

とは言っても、機能はまだ私には有効です。警告/エラー以外に、アプリの機能に問題がありますか?

131
KevinH

私は数時間この問題に苦労していました、私はすべての関連トピックを読みました、そして、私のデバイスのプライバシー設定の下で、私のアプリへのカメラアクセスがブロックされたのでエラーが引き起こされたことを知りました!私はカメラへのアクセスを否定したことがないし、私はそれがどのようにブロックされたのかわからないが、それが問題でした!

45
Pantelis Proios

私は上の@ gregの答えにコメントするのに十分な評判ポイントを持っていないので、ここに私の所見を追加します。 iPadとiPhoneの両方にSwiftプロジェクトがあります。メインのView Controllerの内部にメソッドがあります(以下の関連ビット)。私が電話でこれをテストすると、すべてが正常に動作し、警告は生成されません。 iPadで実行すると、すべてが正しく機能しますが、ビューのスナップショットに関する警告が表示されます。ただし、興味深いことに、Popoverコントローラを使用せずにiPadを実行した場合、警告なしにすべてが正しく機能します。残念なことに、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);
        }
    });
33
dlw

コールバックからUIAlertViewデリゲートへのUIImagePickerController presentViewController:を呼び出した後、これに遭遇しました。 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];
    });
}
16
greg

私はいくつかのビューをアニメートするときにこの問題を抱えていました、そして、アプリはバックグラウンドモードに入りそして戻ってくるでしょう。私はフラグisActiveを設定することによってそれを処理しました。でNOに設定します

- (void)applicationWillResignActive:(UIApplication *)application

そしてYES

- (void)applicationDidBecomeActive:(UIApplication *)application

それに応じて、ビューをアニメートまたはアニメートしないでください。問題の世話をした。

12
byedissident

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

View Controllerを表示する前にviewプロパティを参照することで、「Snapshotting a a 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];
10
Steve Shepard

画像の取り込み後に黒いプレビューで問題が発生している場合は、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
Dan

私は同じ問題を見つけてすべてを試しました。 Objective-CとSwiftの2つの異なるアプリケーションがありますが、どちらも同じ問題があります。エラーメッセージがデバッガに表示され、最初の写真の後に画面が黒くなります。これはiOS> = 8.0でのみ起こります、明らかにそれはバグです。

私は難しい回避策を見つけました。 imagePicker.showsCameraControls = falseでカメラコントロールをオフにして、足りないボタンがある独自のoverlayViewを作成します。これを行う方法についてはさまざまなチュートリアルがあります。変なエラーメッセージは表示されたままですが、少なくとも画面が真っ暗になることはなく、実用的なアプリがあります。

5
Thomas Zimmer

これは組み込みのImagePickerControllerのバグかもしれません。私のコードは動作していますが、時折iPhone 6 Plusでクラッシュします。

私は他の答えによって提案されたすべての解決策を試しましたが、運がありませんでした。 JPSImagePickerController に切り替えた後、問題は最終的に解決されました。

5
JonSlowCN

プロパティとしてUIImagePickerControllerを使用している場合、この警告は消えます。 xcode は、関数内でUIImagePickerControllerをインスタンス化している場合、UIImagePickerControllerからの結果を使用していないと想定します。

3
Antony Ouseph

私はこれがiOS 8.0の単なるバグであると確信しています。それはあなたが上記でやっているようにUIImagePickerControllerを提示することを試みること以上のことをしない最も単純なPOCアプリで再現可能です。さらに、私の知る限りでは、画像ピッカー/カメラを表示するための代替パターンはありません。 AppleのUsing UIImagePickerControllerサンプルアプリをダウンロードして実行することもできます。そのまま使用すると、同じエラーが発生します。

とは言っても、機能はまだ私には有効です。警告/エラー以外に、アプリの機能に問題がありますか?

3
Gaurav Patel

私はすべてを試してみました、私の問題はそれらが示した直後にカメラと写真ライブラリのための画像ピッカーが消えたということでした。次の行で解決しました(Swift)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
3
Waffeln

このメソッドを呼び出すとうまくいきました。あなたの見解を示した後にそれを置きなさい。

[yourViewBeingPresented.view layoutIfNeeded];
2
Bobby

カメラを開けているときにコンソールに以下のようなメッセージが表示され、同じバグが発生しました。

'レンダリングされていないビューをスナップショットすると、スナップショットが空になります。スナップショットの前または画面の更新後のスナップショットの前に、少なくとも1回はビューがレンダリングされていることを確認してください。

Info.plist file.itのBundle表示名に問題がありました。空のBundle display name.itが原因で、カメラのアクセス許可に関するアラートが表示されませんでした。ビューのレンダリングをブロックしました。

あなたのアプリがそこにリストされていない場合、問題はビューではなく許可なしにそれを提示することによってそれを提示することによってあなたはそれをチェックすることができます - >プライバシー - >カメラ。

1
Shabeer Ali

私はこの問題に遭遇しました。カメラを呼び出してビューを解放すると、この問題が発生しました。たとえば、カメラを呼び出してviewDidDisappearメソッドでview nilを設定すると、カメライベントのコールバックがないため、このエラーが発生します。このエラーについてもこのケースについて確かめてください。

1
Gobi M

私はPhonegapを使用していますが、このスレッドはGooglingがエラーメッセージに関して最初のスレッドとして来ることを続けます。

私にとっては、この問題はimagetypeを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});

あなたの走行距離は異なるかもしれませんが、それは私にとってトリックでした。

1
Jannunen

あるいは、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
    }
}

Objective-C:

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

    return image;
}

また見なさい:

1
Eric

私も同じ問題に遭遇し、私はカメラが利用可能かどうかを確認することでそれを解決しました:

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

私の場合(XCode 7とiOS 9)、私はUINavigationControllerを "hidden"にしているので、カメラやロールを提示するためにUINavigationControllerDelegateを追加しなければなりません。 And pickerControllerDelegate.selfもエラーを表示しません!