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


228

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

}];

何か案が?


3
同じ問題があり、さらにこのバグがアプリをときどきクラッシュさせます。アップデート8.0.2でこのバグが修正されることを願っています。iOS7でアプリを実行すると、馬鹿げた警告なしにチャームのように機能します。iOS 8が安定するまでの道のりは長いようです。
NCFUSN 2014

9
8.0.2の更新を伴うイベントこの問題は依然として持続します
ArdenDev 2014年

2
私も同じ問題を抱えていました。写真を撮った後、別のスレッドで処理を行っていました。コードをメインスレッドに移動した後は、すべて問題ありませんでした。dispatch_async(dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{つまり、以前のコードは次のとおりです。これを次のように変更しましたdispatch_async(dispatch_get_main_queue(), ^{
mikeyq6 '10

9
iOS 8.1でも同じ問題が発生
Raptor

12
iOS 9でも同様です。
Sebyddd

回答:


131

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

そうは言っても、機能はまだ私のために動作します。警告/エラー以外に、アプリの機能に問題がありますか?


2
おそらくそれはバグです。コードも私にとってはうまく機能しています。
souvickcse 2014

4
@souvickcseこのエラーも発生しています。それが発生するときはいつでも、新しい写真が撮られるとポップアップする画像プレビューは完全に真っ黒です。ただし、画面下部の[撮り直し]ボタンと[写真を使用]ボタンは引き続き表示され、正しく機能します。あなたはこれと同じ行動を目撃していますか?
Barry Beerman 2014

3
:私はここにある最新のPhoneGapのカメラプラグインベースライン使用してい@souvickcse github.com/apache/cordova-plugin-cameraを。すべてがiPhone 5にiOSの7.1ランニングと罰金に動作しますが、私はそれはiPhone 6上のiOS 8を使用して正常に動作し取得する方法を見つけることができません
バリーBeerman

2
iOS8.1ファイナルでの私と同じ
fvisticot 2014年

4
IOS 9に
も引き続き

45

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


4
実際にうまくいったかどうかはわかりませんが、うまくいきませんでした。@KevinHが正しいことを願っています。
Deepak Thakur 2014年

4
いいえ、私の場合、そのアプリのカメラへのアクセスはオンになっています。しかし、これは間接的にではあるが設定によって引き起こされる可能性があると私は確信しています。設定への変更はすぐに有効にならない場合があります。クパチーノの誰かがどこかで同期するように呼び出しを最適化している必要があります
Anton Tropashko

この提案で問題は解決しました。以前にアプリでカメラセレクターが表示されたときに、[許可しない]に触れていました。カメラにアクセスするたびに尋ねられると思いましたが、そうではありませんでした。[設定]> [プライバシー]> [カメラ]に移動して、アプリのスライダーをオンにする必要がありました。その後、正しく動作しました。Appleの側では毎回尋ねないように馬鹿げているようです...
John Contarino

正確に言うと、この種の間違いで問題が発生したと考えることができない場合があります。非常に参考にTHXのバディ
Mr.Javed Multani

最適なオプションは、カメラを使用して機能がアクティブかどうかを検出する前であり、アクティブでない場合は、設定でカメラがアクティブになるまで写真を撮ることができないことをユーザーに警告します。iOS 10では、特定のアプリ設定にユーザーを送ることができます(iOS 8より前は可能でしたが、正しく思い出せば、iOS 8および9では不可能です)。
2017

33

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

iOS 9.0.2でもエラーメッセージが表示されるため、これは正しい提案のようです。iPhone専用アプリを持っていますが、iPad Miniで実行すると、イメージピッカーを表示するとそのメッセージが表示されます。なんらかの理由でiOSはiPadアプリを実行していると思います。
John Tracid、2015年

16

コールバックから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];
    });
}

これは私のためにそれを解決したものです。UIAlertActionのアクションブロック内からUIImagePickerControllerを提示しようとしました。
josefdlange 2015年

alertViewは非推奨になりましたが、代わりにUIAlertViewControllerアクション内で非同期を使用した場合、これは機能しますか?
DrPatience 2015年

@DrPatience確かに。dispatch_asyncは、どこでも使用できます。それが必要かどうかはわかりません(コードによって異なります)。GCDについて読んでください-非常に多くの用途があります。
集合

12

一部のビューをアニメーション化するとこの問題が発生し、アプリがバックグラウンドモードになって戻ってきます。isActiveフラグを設定して処理しました。私はそれをNOに設定しました

- (void)applicationWillResignActive:(UIApplication *)application

そしてYES

- (void)applicationDidBecomeActive:(UIApplication *)application

それに応じて私の見解をアニメーション化するか、アニメーション化しないか。問題の世話をしました。


11

私はUIAlertControllerStyleActionSheetでこれを行い、ユーザーにカメラで写真を撮るか、ライブラリから写真を使用するオプションを与えました。

エラーメッセージにシンボリックブレークポイントを試しました ここに画像の説明を入力してください

これは、プレゼンテーション中にUICollectionViewをインターンで使用するとエラーが発生することを示しています

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

ここに画像の説明を入力してください

プレゼンテーションの前にフレームを明示的に設定することでこれを修正しました

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

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

これは、ほぼ信じられないほど役立つヒントです。ありがとうございました!!!!(私の場合、まだ警告が表示されますが、アプリはクラッシュしません。)
Fattie

ただし、を追加するとcameraOverlayView、残念ながら、このヒントを適用してもこの問題が発生します。
Fattie

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

1
完全に私の日を救った!私は上記​​の方法を試しましたが、どれもうまくいきませんでした、そしてこれはうまくいきました
スタン

ソリューションが機能していません。そのときに画像をキャプチャすると、StatusBarは既に非表示になっていると思います。
Mihir Oza 2016

5

私は同じ問題を見つけ、すべてを試しました。私は2つの異なるアプリを持っています。1つはObjective-Cで、もう1つはSwiftです。どちらにも同じ問題があります。エラーメッセージがデバッガーに表示され、最初の写真の後に画面が黒くなる。これはiOS 8.0以上でのみ発生します。明らかにバグです。

難しい回避策を見つけました。imagePicker.showsCameraControls = falseでカメラコントロールをオフにして、ボタンが欠落している独自のoverlayViewを作成します。これを行う方法については、さまざまなチュートリアルがあります。奇妙なエラーメッセージは残りますが、少なくとも画面が黒くならず、動作するアプリがあります。


私はあなたとまったく同じ問題を抱えていました、以下の私の答えを見てください。
Dan

5

これは組み込みのImagePickerControllerのバグである可能性があります。コードは機能していますが、iPhone 6 Plusで時々クラッシュします。

他の回答で提案されているすべての解決策を試しましたが、うまくいきませんでした。JPSImagePickerControllerに切り替えた後、問題は最終的に解決しました


3

私はすべてを試しましたが、私の問題は、カメラと写真ライブラリの画像ピッカーが表示された直後に表示されなくなったことでした。私は次の行でそれを解決しました(迅速)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

3

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

そうは言っても、機能はまだ私のために動作します。警告/エラー以外に、アプリの機能に問題がありますか?


3

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


2

このメソッドを呼び出すとうまくいきました。ビューを提示した後に配置します。

[yourViewBeingPresented.view layoutIfNeeded];

1

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

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

1
アプリのカメラへのアクセスを拒否したにもかかわらず、isSourceTypeAvailableがtrueを返します。カメラへのアクセスが拒否された場合、ディスプレイには何も表示されません。
Καrτhικ

1

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


1

同じバグが発生し、カメラを開くとコンソールに次のようなメッセージが表示されました。

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

私にとっての問題は、Info.plistファイルのバンドルの表示名に問題がありました。どうにかして空になりましたが、アプリ名をそこに入力すると、正常に機能します。ビューのレンダリングをブロックしました。

問題はビューにありませんでしたが、許可なしにそれを提示することによって。設定->プライバシー->カメラで確認できます。アプリがリストにない場合、問題は同じである可能性があります。


1

私はPhonegapを使用していますが、このスレッドはエラーメッセージについてグーグルするときに最初のスレッドとして表示され続けます。

私にとって、この問題は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

または、次の使用を検討して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;
}

こちらもご覧ください:


0

私の場合(XCode 7とiOS 9)、私はUINavigationController"hidden" を使用しているのでUINavigationControllerDelegate、現在のカメラまたはロールに追加する必要があり、想定どおりに動作します!And pickerControllerDelegate.selfエラーも表示されません!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.