Captura de pantalla completa con barra de estado en iOS mediante progtwigción

Estoy usando este código para capturar una captura de pantalla y savela en el álbum de fotos.

-(void)TakeScreenshotAndSaveToPhotoAlbum { UIWindow *window = [UIApplication shanetworkingApplication].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); } 

Pero el problema es que cada vez que se guarda la captura de pantalla, veo que la barra de estado del iPhone no se captura. En cambio, aparece un espacio en blanco en la parte inferior. Como la siguiente image: introduzca la descripción de la imagen aquí

¿Qué estoy haciendo mal?

La barra de estado está en realidad en su propia UIWindow, en su código solo está representando la vista de su viewcontroller, que no incluye esto.

El método de captura de pantalla "oficial" estaba aquí, pero ahora parece haber sido eliminado por Apple, probablemente debido a que era obsoleto.

En iOS 7, ahora hay un nuevo método en UIScreen para get una vista que UIScreen los contenidos de toda la pantalla:

 - (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates 

Esto le dará una vista que luego puede manipular en la pantalla para varios efectos visuales.

Si desea dibujar la jerarquía de vista en un context, debe iterar a través de las windows de la aplicación ( [[UIApplication shanetworkingApplication] windows] ) y llamar a este método en cada uno:

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

Es posible que pueda combinar los dos enfoques anteriores y tomar la vista de instantánea, luego use el método anterior en la instantánea para dibujarlo.

El método de captura de pantalla "oficial" sugerido no captura la barra de estado (no está en la list de windows de la aplicación). Como se probó en iOS 5.

Creo que esto es por razones de security, pero no se menciona en los documentos.

Sugiero dos opciones:

  • Dibuje una image de barra de estado de stub de los resources de su aplicación (opcionalmente, indicador de time de actualización);
  • capture solo su vista, sin barra de estado o recortar image después (el tamaño de la image será diferente de la resolución estándar del dispositivo); El marco de la barra de estado se conoce a partir de la propiedad correspondiente del object de aplicación.

Aquí está mi código para tomar una captura de pantalla y almacenarla como NSData (dentro de una IBAction). Con el sotnetworking NSData entonces puede compartir o enviar un correo electrónico o lo que quiera hacer

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

Lo siguiente funciona para mí, capturando la barra de estado bien (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()