Cómo get una image ENTER desde UIWebView, incluido el contenido fuera de pantalla

Tengo un método que uso para get imágenes de varias vistas en mi aplicación de iOS para permitir que los usuarios envíen pantallas de correo electrónico. La mayoría de las pantallas donde dibujo funcionan bien, pero cuando uso esta técnica con una UIWebView solo obtengo la parte visible de la pantalla. Cualquier cosa fuera de la pantalla no está incluida en la image procesada. He estado cavando por aquí en Stack, pero hasta ahora nada de lo que he encontrado funciona ?!

Aquí está el método que uso actualmente:

-(NSData *)getImageFromView:(UIView *)view { NSData *pngImg; CGFloat max, scale = 1.0; CGSize size = [view bounds].size; // Scale down larger images else we run into mem issues with mail widget max = (size.width > size.height) ? size.width : size.height; if( max > 960 ) scale = 960/max; UIGraphicsBeginImageContextWithOptions( size, YES, scale ); CGContextRef context = UIGraphicsGetCurrentContext(); [view.layer renderInContext:context]; pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() ); UIGraphicsEndImageContext(); return pngImg; } 

Wow, la respuesta fue estúpidamente simple … estaba cavando por todo el lugar mirando varias cosas relacionadas con la printing / PDF … entonces se me ocurrió, ¿por qué no simplemente configuró la vista EN EL CONTEXTO a un tamaño que encaja? ¡Funcionó!

ADVERTENCIA: No garantizamos que no te encuentres con problemas de mem con esto y sugiero que hagas esto dentro de un pool @autoreleasepool y que consideres hacer algo de escala como lo hago en el ejemplo, pero THIS WORKS y es en lo que decidí:

 -(NSData *)getImageFromView:(UIView *)view // Mine is UIWebView but should work for any { NSData *pngImg; CGFloat max, scale = 1.0; CGSize viewSize = [view bounds].size; // Get the size of the the FULL Content, not just the bit that is visible CGSize size = [view sizeThatFits:CGSizeZero]; // Scale down if on iPad to something more reasonable max = (viewSize.width > viewSize.height) ? viewSize.width : viewSize.height; if( max > 960 ) scale = 960/max; UIGraphicsBeginImageContextWithOptions( size, YES, scale ); // Set the view to the FULL size of the content. [view setFrame: CGRectMake(0, 0, size.width, size.height)]; CGContextRef context = UIGraphicsGetCurrentContext(); [view.layer renderInContext:context]; pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() ); UIGraphicsEndImageContext(); return pngImg; // Voila an image of the ENTIRE CONTENT, not just visible bit } 

Creé una categoría para esto hace un time. Funciona si (y solo si) la vista web se almacena en memory caching, de lo contrario, las partes de la página aparecerán en blanco.

 #import "UIWebView+Screenshot.h" #import <QuartzCore/QuartzCore.h> @implementation UIWebView (Screenshot) - (UIImage *)screenshot { UIImage *img = nil; UIGraphicsBeginImageContextWithOptions(self.scrollView.contentSize, self.scrollView.opaque, 0.0); { CGPoint savedContentOffset = self.scrollView.contentOffset; CGRect savedFrame = self.scrollView.frame; self.scrollView.contentOffset = CGPointZero; self.scrollView.frame = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height); [self.scrollView.layer renderInContext: UIGraphicsGetCurrentContext()]; img = UIGraphicsGetImageFromCurrentImageContext(); self.scrollView.contentOffset = savedContentOffset; self.scrollView.frame = savedFrame; } UIGraphicsEndImageContext(); return img; } @end 

Puede acercar la vista de la pantalla de manera que todo el contenido se ajuste a la pantalla … pero esto solo funcionará si la image está fuera de la pantalla horizontalmente. Si el UIWebView es más largo que la pantalla, esto no hará mucho.

 [webview.scrollView setZoomScale:webview.scrollView.minimumZoomScale animated:NO];