Cómo capturar la captura de pantalla de la vista actual y reutilizarla en el código? (iPhone SDK)

Estoy intentando hacer la transición de una UIView a otra, cuando el usuario gira el dispositivo. Esto, en sí mismo, no es difícil. Sin embargo, dado que estoy mostrando contenido completamente diferente después de la rotación, la animación predeterminada proporcionada por UIKit (rotando la vista que se muestra actualmente) es conceptualmente inapropiada.

Simplemente deshabilitar la animación e intercambiar las vistas de repente es tolerable, pero está muy por debajo del brillo que estoy desarrollando en el rest de la aplicación. Lo que preferiría hacer es esto:

Cuando se llama a la instrucción AuthorAteToInterfaceOrientation: me gustaría obtener una instantánea de vista opaca, una captura de pantalla si se quiere, de la vista del usuario antes de la rotación. Luego, una vez que se completa la rotación y el sistema ha aplicado la vista, se transforma, etc., puedo mostrar la vista de instantánea que guardé y animar una transición de mi elección a mi nueva vista. Después de que se complete, puedo lanzar mi instantánea y continuar.

¿Hay alguna manera de hacer esto que no sea costosa?

La única otra opción en la que puedo pensar es devolver NO en todas las orientaciones que no sean las predeterminadas, y luego reactjsr aplicando mis propias animaciones y transformaciones. Preferiría utilizar el sistema para hacer esto, sin embargo, como creo que es probable que hacerlo yo mismo podría causar un comportamiento de teclado “indefinido” en la vista girada manualmente, etc.

¿Pensamientos?

Puedo garantizarle que [window drawRect:] no funcionará. La mayoría de las vistas no implementan drawRect: y ciertamente no es recursiva como en el mac.

drawInContext: también está bastante manguera simalarly, ya que fundamentalmente le pide a la capa que dibuje a sí misma, no sus subcapas recursivamente. “La implementación predeterminada no hace nada”. lo dice todo.

Implementando esto para la aplicación Clif Bar Save Our Snow en la tienda de aplicaciones haciendo lo siguiente:

  • Recorra la jerarquía de capas recursivamente, obteniendo los contenidos de cada capa. Si huele como una imagen, use los métodos CGContext para dibujarlo en su contexto.
  • Mientras camina, asegúrese de aplicar las transformaciones / posiciones de cada capa a medida que llama recursivamente

Sí, un dolor bastante grande en el culo. Pero sí, funciona bastante bien y Apple lo consiguió.

- (UIImage *)captureView:(UIView *)view { CGRect screenRect = [[UIScreen mainScreen] bounds]; UIGraphicsBeginImageContext(screenRect.size); CGContextRef ctx = UIGraphicsGetCurrentContext(); [[UIColor blackColor] set]; CGContextFillRect(ctx, screenRect); [view.layer renderInContext:ctx]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

Encontrado esto aquí:

http://discussions.apple.com/thread.jspa?messageID=8358740

Este código funcionó para mí

 - (UIImage *)captureScreenInRect:(CGRect)captureFrame { CALayer *layer; layer = self.view.layer; UIGraphicsBeginImageContext(self.view.bounds.size); CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame); [layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return screenImage; } 

En Mac esto es tan fácil … solo necesitas -bitmapImageRepForCachingDisplayInRect: pero por supuesto iPhone no tiene tal cosa.

Creo que atacaría esto configurando un contexto de gráficos y llamando a [window drawRect:...] para capturar la imagen actual de la pantalla. Esto está un poco desajustado, porque realmente no se supone que vayas a llamar -drawRect: tú mismo. Estaría un poco nervioso de los efectos secundarios al hacer esto, pero puede estar bien. Si se trata de una vista de pantalla completa que usted controla, puede, por supuesto, levantar el código de dibujo de -drawRect: por lo que no está llamando directamente.

Un enfoque similar sería usar CALayer -drawInContext: de la presentación actual. Eso podría ser un poco más “de especificación”, ya que es legal pasar ese contexto. Pero no sé si realmente podría obtener todas las sub-vistas correctamente. Puede depender de la naturaleza de su UIWindow.

De todos modos, gran pregunta. Tal vez alguien tenga una solución más inteligente, pero esta es la forma en que lo atacaría.

EDITAR: Gracias a Rob Terrell, y su inteligente UIApplication + TVOut.m , me presentaron el método privado UIGetScreenImage () que devuelve un CGImageRef. Si está dispuesto a recurrir a métodos privados, esa es una buena opción para usted. Dado su nombre y funcionalidad, parece bastante estable para mí y parece poco probable que viole la intención de Apple. También me encontré con una discusión bastante agradable sobre Air Source . Lee los comentarios de varios enlaces.

    Intereting Posts