14

このコードを使用して、スクリーンショットをキャプチャし、フォトアルバムに保存しています。

-(void)TakeScreenshotAndSaveToPhotoAlbum
{
   UIWindow *window = [UIApplication sharedApplication].keyWindow;

   if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
       UIGraphicsBeginImageContextWithOptions(window.bounds.size, NO, [UIScreen mainScreen].scale);
   else
       UIGraphicsBeginImageContext(window.bounds.size);

   [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
   UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}

しかし、問題は、スクリーンショットが保存されるたびに、iPhoneのステータスバーがキャプチャされないことです。代わりに、下部に空白が表示されます。次の画像のように: ここに画像の説明を入力してください

私は何が間違っているのですか?

4

7 に答える 7

18

ステータスバーは実際には独自の UIWindow にあります。コードでは、これを含まないビューコントローラーのビューのみをレンダリングしています。

「公式の」スクリーンショット メソッドはここにありましたが、おそらく廃止されたため、Apple によって削除されたようです。

iOS 7UIScreenでは、画面全体のコンテンツを保持するビューを取得するための新しいメソッドが追加されました。

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates

これにより、さまざまな視覚効果のために画面上で操作できるビューが得られます。

ビュー階層をコンテキストに描画する場合は、アプリケーションのウィンドウ ( [[UIApplication sharedApplication] windows]) を反復処理し、それぞれでこのメソッドを呼び出す必要があります。

- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates

上記の 2 つのアプローチを組み合わせてスナップショット ビューを取得し、スナップショットで上記の方法を使用して描画することができます

于 2011-12-14T18:11:53.503 に答える
7

推奨される「公式」スクリーンショット方法はステータスバーをキャプチャしません(アプリケーションのWindowsリストにはありません)。iOS5でテスト済み。

これはセキュリティ上の理由によると思いますが、ドキュメントには記載されていません。

私は2つのオプションを提案します:

  • アプリのリソースからスタブステータスバーの画像を描画します(オプションで時間インジケーターを更新します)。
  • ステータスバーなしでビューのみをキャプチャするか、後で画像をトリミングします(画像サイズは標準のデバイス解像度とは異なります)。ステータスバーフレームは、アプリケーションオブジェクトの対応するプロパティからわかります。
于 2011-12-25T23:54:35.263 に答える
6

スクリーンショットを撮り、それを NSData として (IBAction 内に) 保存するコードを次に示します。sotred NSDataを使用すると、共有したり、電子メールで送信したり、やりたいことが何でもできます

CGSize imageSize = [[UIScreen mainScreen] bounds].size;
        if (NULL != UIGraphicsBeginImageContextWithOptions)
            UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
        else
            UIGraphicsBeginImageContext(imageSize);

        CGContextRef context = UIGraphicsGetCurrentContext();

        // Iterate over every window from back to front
        for (UIWindow *window in [[UIApplication sharedApplication] windows])
        {
            if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen])
            {
                // -renderInContext: renders in the coordinate space of the layer,
                // so we must first apply the layer's geometry to the graphics context
                CGContextSaveGState(context);
                // Center the context around the window's anchor point
                CGContextTranslateCTM(context, [window center].x, [window center].y);
                // Apply the window's transform about the anchor point
                CGContextConcatCTM(context, [window transform]);
                // Offset by the portion of the bounds left of and above the anchor point
                CGContextTranslateCTM(context,
                                      -[window bounds].size.width * [[window layer] anchorPoint].x,
                                      -[window bounds].size.height * [[window layer] anchorPoint].y);

                // Render the layer hierarchy to the current context
                [[window layer] renderInContext:context];

                // Restore the context
                CGContextRestoreGState(context);
            }
        }

        // Retrieve the screenshot image
        UIImage *imageForEmail = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

    NSData *imageDataForEmail = UIImageJPEGRepresentation(imageForEmail, 1.0);
于 2013-03-03T09:11:49.390 に答える
1

上記の質問の回答Objective-Cはすでにそこに書かれています。これSwiftが上記の質問のバージョンの回答です。

Swift 3+の場合

スクリーンショットを撮り、それを使用してどこかに表示したり、Web 経由で送信したりします。

extension UIImage {
    class var screenShot: UIImage? {
        let imageSize = UIScreen.main.bounds.size as CGSize;
        UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
        guard let context = UIGraphicsGetCurrentContext() else {return nil}
        for obj : AnyObject in UIApplication.shared.windows {
            if let window = obj as? UIWindow {
                if window.responds(to: #selector(getter: UIWindow.screen)) || window.screen == UIScreen.main {
                    // so we must first apply the layer's geometry to the graphics context
                    context.saveGState();
                    // Center the context around the window's anchor point
                    context.translateBy(x: window.center.x, y: window.center
                        .y);
                    // Apply the window's transform about the anchor point
                    context.concatenate(window.transform);
                    // Offset by the portion of the bounds left of and above the anchor point
                    context.translateBy(x: -window.bounds.size.width * window.layer.anchorPoint.x,
                                         y: -window.bounds.size.height * window.layer.anchorPoint.y);

                    // Render the layer hierarchy to the current context
                    window.layer.render(in: context)

                    // Restore the context
                    context.restoreGState();
                }
            }
        }
        guard let image = UIGraphicsGetImageFromCurrentImageContext() else {return nil}
        return image
    }
}

上のスクリーンショットの使用

  • 上記のスクリーンショットを UIImageView に表示させます

    yourImageView = UIImage.screenShot
    
  • 画像データを取得して保存/Web 経由で送信

    if let img = UIImage.screenShot {
        if let data = UIImagePNGRepresentation(img) {
            //send this data over web or store it anywhere
        }
    }
    
于 2018-03-24T20:40:43.667 に答える
-1

以下は私にとってはうまくいき、ステータスバーをうまくキャプチャします(iOS 9、Swift)

let screen = UIScreen.mainScreen()
let snapshotView = screen.snapshotViewAfterScreenUpdates(true)
UIGraphicsBeginImageContextWithOptions(snapshotView.bounds.size, true, 0)
snapshotView.drawViewHierarchyInRect(snapshotView.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
于 2016-03-05T02:50:46.347 に答える