2008-12-22 3 views
7

? Estoy intentando dibujar un gráfico que es indefinidamente grande horizontalmente, y de la misma altura que la pantalla. He agregado un UIScrollView y una subclase de UIView dentro de él, que implementa el método -drawRect:. En el simulador, todo funciona bien, pero en el dispositivo, parece que no puede dibujar el gráfico una vez que alcanza un determinado tamaño.¿Cómo puedo desplazar una UIView de tamaño indefinido dentro de un UIScrollView

Ya estoy almacenando en caché casi todo lo que puedo, y básicamente solo llamo a CGContextAddLineToPoint en la sección -drawRect:. Solo dibujo lo que está visible en la pantalla. Tengo un delegado en el UIScrollView que escucha -scrollViewDidScroll: que luego le dice al gráfico que vuelva a dibujarse ([graphView setNeedsDisplay]).

Encontré un método que me dice que debe anular el método +layerClass y devolver [CATiledLayer class]. Esto permite que el gráfico dibuje realmente en el dispositivo, pero funciona muy mal. Es increíblemente lento dibujar realmente, y el desvanecimiento que ocurre es indeseable.

¿Alguna sugerencia?

Respuesta

3

Bueno, aquí está mi respuesta: Básicamente hice algo similar a cómo funciona la UITableView con las células: Tengo un NSMutableSet de objetos GraphView que almacenan gráficos no utilizados. Cuando una sección de la vista de desplazamiento se hace visible, tomo una vista de gráfico de ese conjunto (o hago una nueva si el conjunto está vacío). Ya tenía una propiedad scrollX para determinar qué parte de ella debía dibujar. Establecí la propiedad scrollX en el valor correcto y, en lugar de usar el ancho de la pantalla, le di un ancho arbitrario para dibujar. Cuando sale de la vista de desplazamiento, se elimina de UIScrollView y se agrega al conjunto.

Me pregunto si realmente incluso tengo que eliminarlos cuando salen de la vista? Puede ser prudente intentar dejarlos y eliminar los que no están en la pantalla solo si recibo una advertencia de poca memoria. Esto podría deshacerse de la pausa cuando sea necesario volver a dibujar una sección de gráfico que no ha cambiado.

Mi salvación aquí fue que mi GraphView ya estaba configurado para dibujar solo una parte del gráfico. Todo lo que tenía que hacer entonces era simplemente hacer más de uno.

2

Creo que esto es una limitación del hardware de gráficos de iPhone. A través de la experimentación, he visto que el iPhone se negará a dibujar un cuadro que sea más grande que 2000 píxeles en altura o ancho. Probablemente tiene algo que ver con el tamaño limitado para los búferes de cuadro en el hardware.

+0

No es una respuesta muy útil, creo. Obviamente, hay una manera de hacerlo, ya que cosas como Google Maps parecen ser capaces de funcionar bien. No está picado en absoluto, y parece ser bastante bueno dibujando rápidamente, incluso cuando tiene que descargar los datos primero. –

+0

Solo digo que no puedes hacerlo con un solo control de IU porque su marco será demasiado grande.Probablemente exista una forma en que puede colocar varias vistas juntas horizontalmente, pero es probable que tenga que gestionarlas usted mismo (destruir/crear sobre la marcha). –

0

Gracias, eso es útil. Una pregunta: ¿qué usaste para el contenido Tamaño de UIScrollView? ¿UIScrollView tolera tamaños de contenido grandes (más de 2000 px) siempre que no esté creando búferes para llenar todo el espacio en su vista de contenido? ¿O está manteniendo UIScrollView un tamaño constante (por ejemplo, 2 anchos de pantalla) y descansa la propiedad UIScrollView contentOffset cada vez que dibuja (utilizando scrollX en lugar de contentOffset para almacenar su posición)?

Creo que respondí mi propia pregunta (esta última parece ser una mejor alternativa), je, pero voy a seguir adelante y publicar esto en caso de que otras personas necesiten una aclaración.

+0

contentSize es tan grande como debe ser (tan ancho como 50500 píxeles en mi caso), con muchas vistas diferentes dentro de él –

+0

¿Ha experimentado almacenar solo objetos CGLayer y CGPoint para cada caché en lugar de una vista completa? Estoy pensando que reduciría los gastos generales, pero no estoy seguro de si eso marcaría una gran diferencia. –

+0

Pensándolo bien, eso no funcionaría porque un CGLayer necesita ser dibujado en algún contexto, por lo que todavía necesita una UIView para dibujar. No importa. –

1

Mire el video de la sesión de la WWDC 2011 titulado "Sesión 104 - Técnicas avanzadas de visualización de desplazamiento".

Cuestiones relacionadas