2012-05-03 10 views
5

que estoy experimentando un problema de redibujo en un CATiledLayer cuando el UIScrollView padre se ha ampliado.CATiledLayer siendo retirado y refrescado la imagen ampliada iPad 3ª generación

Estoy prestando una página PDF en un CATiledLayer respaldado UIView. Tiene otro UIImageView detrás de él, que contiene una imagen de baja resolución de la página que dibujará CATiledLayer. Cuando hago zoom, funciona como se esperaba. El CATiledLayer renderizará una imagen de mayor resolución de acuerdo con el nivel de zoom.

El problema ocurre después del acercamiento. Si hago zoom, simplemente deje el iPad solo, la imagen mostrada se borra y luego se reafirma. Parece que se está eliminando CATiledLayer, ya que veo la imagen borrosa de baja resolución en la vista de respaldo, luego el CATiledLayer se vuelve a dibujar, es decir, veo el efecto de mosaico y el reafilado de la imagen. Esto sucede si dejo la aplicación solo y espero entre 30 y 40 segundos. Solo lo he observado en el iPad de tercera generación (nuevo iPad, iPad3, lo que sea). También estoy probando en iPad2s y todavía no he encontrado el problema.

¿Alguien más ha encontrado este problema? ¿Alguna causa conocida y, posiblemente, soluciones?

Editar:

Mis métodos UIScrollViewDelegate son los siguientes:

// currentPage, previousPage, and nextPage are the pdf page views 
// that are having the refresh problem 

- (void)positionBufferedPages { 
    // performs math {code omitted} 

    // then sets the center of the views 
    [previousPage.view setCenter:...];   
    [nextPage.view setCenter:...]; 
} 

- (void)hideBufferedPages { 
    if ([previousPage.view isDescendantOfView:scrollView]) { 
    [previousPage.view removeFromSuperview]; 
    } 

    if ([nextPage.view isDescendantOfView:scrollView]) { 
    [nextPage.view removeFromSuperview]; 
    }   
} 

- (void)showBufferedPages { 
    if (![previousPage.view isDescendantOfView:scrollView]) { 
    [scrollView addSubview:previousPage.view]; 
    } 

    if (![nextPage.view isDescendantOfView:scrollView]) { 
    [scrollView addSubview:nextPage.view]; 
    } 

    if (![currentPage.view isDescendantOfView:scrollView]) { 
    [scrollView addSubview:currentPage.view]; 
    } 
} 

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 
    return currentPage.view; 
} 

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view { 
    [self hideBufferedPages]; 
} 

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollViewParam withView:(UIView *)view atScale:(float)scale { 
    [self positionBufferedPages]; 
    [self showBufferedPages];  
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView { 
    // nothing relating to the pdf page view 
    // but does set the center of some other subviews on top of the pdf page views 
} 

No está seguro de lo útil que será, sin embargo, como el ScrollView no está recibiendo la carga, mientras que el problema ocurre. Como se mencionó anteriormente, la página pdf se carga en CATiledLayer, luego dejo solo el iPad (el dispositivo no recibe ninguna entrada) y CATiledLayer se redibujará solo.

También he intentado llamadas a la captura de setNeedsDisplay, setNeedsDisplayInRect:, setNeedsLayout y setNeedsDisplayOnBoundsChange: tanto en la vista y la capa de tejas, pero el redibujado sucede sin ninguna de esas funciones recibiendo llamadas. drawLayer:inContext: se llama, por supuesto, pero la traza solo muestra algunas llamadas de Cuarzo que se inician en una cadena de fondo (como se esperaba, ya que las capas de mosaico preparan el contenido en segundo plano), por lo que tampoco sirve de nada.

¡Gracias de antemano!

+0

¿Podría ser por la pantalla de retina de alta resolución del ipad 3? ¿Está configurando correctamente el contenido de CATiledLayer? También en el código de representación de creación de PDF personalizado debe utilizar UIGraphicsBeginImageContextWithOptions y establecer la escala en consecuencia – Lefteris

+0

No estoy usando UIGraphicsBeginImageContextWithOptions, pero utilizo CGContextScaleCTM para establecer la escala. ¿Hay una diferencia? Parece que estoy renderizando el pdf correctamente. Mi problema es que CATiledLayer de alguna manera se redibuja sin razón alguna después de un tiempo. – Altealice

+0

Debe establecer CATiledLayer contentsScale en la escala [[UIScreen mainScreen]] – Lefteris

Respuesta

1

¿Cómo se ve el uso de la memoria de su aplicación? CATiledLayer descartará su caché y volverá a dibujar si se produce una advertencia de memoria. Lo he visto hacer esto incluso sin que se hayan enviado advertencias de memoria a la aplicación (solo una carga de memoria superior a la habitual). Usa instrumentos para ver el uso de la memoria. Es posible que necesite usar el instrumento OpenGL ES Driver para ver qué sucede con la memoria de gráficos.

+0

Estoy registrando advertencias de memoria, pero no se activa cuando ocurre el redibujado. Intentaré verificar con los instrumentos. Gracias por la información. – Altealice

+0

Entonces, ¿cómo resolvió este problema? Muchos de nosotros estamos teniendo el mismo problema y una solución sería genial – Brodie

1

He tenido exactamente el mismo problema. En mi caso, fue causado por el uso de la función UIGraphicsBeginImageContext(); esta función no tiene en cuenta la escala, lo que genera problemas en una pantalla retina. La solución fue reemplazar la llamada con UIGraphicsBeginImageContextWithOptions(), con el parámetro scale (= third) establecido en 0.0.

Si basó su código en el código de muestra de Zooming PDF Viewer de Apple, como yo, es probable que esto también solucione su problema.

+0

el ajuste a escala a 0.0 es falso ... debe establecerse así: UIGraphicsBeginImageContextWithOptions (frame.size, NO, [[UIScreen mainScreen] scale]); – Lefteris

+0

Su camino también funciona, por supuesto, pero establecer la escala en 0.0 tiene el mismo efecto. http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html – Stuart

+0

Interesante. Gracias. Sin embargo, no estoy llamando a UIGraphicsBeginImageContext(), ya que estoy dibujando usando 'drawlayer: inContext:'. ¿Estás usando un método diferente? – Altealice

1

Disparo a larga distancia, ¿hay alguna posibilidad de que esté llamando a algún método en las vistas desde el hilo no principal? Todo tipo de cosas funky inesperadas pueden suceder si lo haces.

+0

Sí, hay cosas sucediendo en el fondo, pero ninguno de ellos deberían estar llamando la vista. Si este es el caso, entonces las cosas de fondo podrían estar consumiendo la memoria y causando que se vuelva a dibujar como dice Josh. Lo verificaré cuando regrese al trabajo mañana. – Altealice

1

Hablé con un ingeniero de Apple sobre esto y la respuesta corta es que iOS solo tiene X cantidad de memoria disponible para almacenar en caché un CATiledLayer y en la pantalla Retina del iPad, hay demasiados píxeles para usar más de uno capa.

He estado utilizando dos CATileLayers para mostrar una vista de mapa y una vista de dibujo en la parte superior. Eliminé el segundo CATiledLayer y el problema desapareció.

+0

Ya veo. Es bueno saberlo. Gracias ¡para compartir! :) – Altealice

Cuestiones relacionadas