21

sourceType カメラで呼び出される UIImagePickerController があり、80% の確率で黒いプレビューが表示されます。約 30 秒待つと、適切なプレビューが表示され、約 50% の確率で正常に表示されますが、再び壊れる可能性があります。

問題の画像はこれに非常に似ています。iDevice カメラがプレビューではなく黒く表示される

他の人は、GCD がカメラに何らかの問題を引き起こしている可能性があり、イメージ ピッカーの読み込み中に UI を更新すると問題が発生することをほのめかしています。この目的のために、メイン スレッドを呼び出すすべての GCD ブロックをロックします。

これは、アクティビティ インジケーターをシミュレートするために回転する画像の例です。

-(void)animateLoadingImage {

if (isMainThreadBlocked) {
    return;
}

self.radians += M_PI_4 / 2;
[UIView beginAnimations:@"progress rotation" context:nil];
[UIView setAnimationDuration:.1];
self.loadingImageView.transform = CGAffineTransformMakeRotation(self.radians);
[UIView commitAnimations];


}

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

これは、ピッカー コントローラーを開こうとすると常に表示されますが、カメラがプレビューを正しく表示している場合でも表示されます。エラーがここにあるとは思いませんが、これも私を悩ませています。

4

7 に答える 7

10

これに対する良い答えはオンラインのどこにもないように思われるので、私はそれを理解するために自分で苦労しなければなりませんでした.

私は ARC を使用しているため (おそらく最近の他のほとんどのユーザーと同様)、上記の回答はあまり役に立ちませんでした。

この黒いカメラの問題は、iOS 7 のメイン スレッドから UIKit を実行することの副作用として発生します。一般に、バックグラウンドの UIKit 操作により、iOS 7 であらゆる種類の奇妙なことが発生します (メモリがすぐに割り当て解除されない、奇妙なパフォーマンス ヒッチ、および黒いカメラの問題)。

これを防ぐには、バックグラウンド スレッドで UIKit を一切実行しないでください。

バックグラウンド スレッドでは実行できないこと: - UIView とサブクラスの割り当て/初期化 - UIView とサブクラスの変更 (例: フレームの設定、.image/.text 属性の設定など)。

さて、メイン スレッドでこのようなことを行う際の問題は、UI のパフォーマンスを台無しにする可能性があることです。そのため、iOS 7 では最適に動作しないこれらすべての iOS 6 の「バックグラウンド ロード」ソリューションが表示されます (つまり、黒いカメラの原因となります)。問題など)。

バックグラウンド UIKit 操作の悪影響を防ぎながら、パフォーマンスを修正するために私が行ったことが 2 つあります。 - バックグラウンド スレッドですべての UIImage を事前に作成して初期化します。メイン スレッドで UIImages を使用して行う必要がある唯一のことは、「imageView.image = preloadedImageObject;」を設定することです。- 可能な限りビューを再利用します。[[UIView alloc] init] をメイン スレッドで実行しても、cellForRowAtIndex で実行している場合や、応答性が非常に重要な別の状況で実行している場合は、依然として問題になる可能性があります。

頑張ってください!アプリの実行中にメモリ使用量を監視することで、どのように動作しているかをテストできます。バックグラウンドUIKit =>メモリ使用量が急速に増加しています。

于 2013-11-14T05:48:22.617 に答える
5

これと同じ問題がありましたが、アプリは写真へのアクセス許可を与えるアラートを表示せず、許可を求めたとして [設定] -> [プライバシー] -> [写真] に表示されませんでした. 許可プロンプトなしで黒い画面を表示するだけです。

私は最終的にこれをinfo.plistまでたどりました。

ここに画像の説明を入力

キー「バンドル表示名」をinfo.plistに追加し、値を空白のままにすると、許可アラートは表示されません。アクセス許可アラートは、この値を取得してアラートに表示するようです。空白のままにすると、単にアラートが表示されません。

値なしで plist にこれがある場合、黒いプレビューが発生する可能性があります。

編集: 私がテストした 3 台の iPhone 6 デバイスすべてをテストしたところ、iPhone 5s はアラートを表示せず、黒い画面でハングアップしました。iPhone 4s および iPhone 6S+ はアラートを表示し、期待どおりに機能しました。

于 2015-11-24T22:30:41.733 に答える
1

私の場合、いくつかのメソッドをメインスレッドに移動する必要がありました。

私のアプリは新しいコンテキストで新しいイメージを作成します。別のスレッドで新しいコンテキストを作成し、CGContext 関数 (CGContextScaleCTM、CGContextTranslateCTM、CGContextConcatCTM など) と [uiimage drawInRect:Mybounds]; を使用できます。

基本的に、コンテキストでレイヤーを描画したときに、renderInContext メソッドをメイン スレッドに移動する必要がありました。

CGSize sizeView = viewPrintBase.frame.size;
UIGraphicsBeginImageContext(sizeView);
currentContext = UIGraphicsGetCurrentContext();

dispatch_sync(dispatch_get_main_queue(), ^{
    [viewPrintBase.layer renderInContext:currentContext];
    [imageViewPhotoUser.layer renderInContext:currentContext];
    if (imageViewMask) {
        [imageViewMask.layer renderInContext:currentContext];
    }
});
[imageSnapShotDrawinfView drawInRect:viewPrintBase.bounds];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGImageRef imageRef = CGImageCreateWithImageInRect([finalImage CGImage], viewPrintBase.bounds);
// or use the UIImage wherever you like
imageSnapShot = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

また、次のようなすべての UI オブジェクトの作成をメイン スレッドに移動する必要がありました。

    __block UIView *viewPrintBase;
dispatch_sync(dispatch_get_main_queue(), ^{
    viewPrintBase = [[UIView alloc]initWithFrame:CGRectMake(0, 0, WIDTH_FINAL_IMAGE, HEIGHT_FINAL_IMAGE)];
    viewPrintBase.backgroundColor = [UIColor whiteColor];
    [viewPrintBase setClipsToBounds:YES];
    //We get the photo user
});

これが役立つことを願っています:)

于 2014-01-07T13:19:44.997 に答える
1

まず、アプリにカメラへのアクセス許可があるかどうかを確認します。アプリで初めてカメラを起動するときに「いいえ」オプションを押したと思います。次に、1 つのことを行います。[設定] -> [プライバシー] -> [カメラ] に移動し、そこでアプリを選択して、オンかオフかを確認してください。これで、アプリでカメラにアクセスできるようになりました。

于 2014-10-14T04:25:36.013 に答える