2009-12-01 7 views
27

Ok, tengo una UITableView con la costumbre UITableViewCell s que contienen cada una UIImageView cuyas imágenes están siendo descargados de forma asíncrona a través de un NSURLConnection. Todas las cosas bastante estándar ...Delayed UIImageView representación en UITableView

El problema es que, cuando la tabla se desplaza, las nuevas imágenes se descargan en segundo plano correctamente pero no se RENDEN hasta que la tabla deje de moverse.

¿Cómo consigo que la tabla muestre su contenido incluso cuando se está moviendo? Gracias.

- ACTUALIZACIÓN -

Después de un vistazo más de cerca, estoy encontrando que los métodos de delegado NSURLConnection no están disparando hasta que la mesa se detiene. No estoy seguro por qué. Cualquier ayuda sería genial.

Respuesta

65

El motivo por el que los mensajes de delegado de conexión no se activan hasta que se detiene el desplazamiento es porque durante el desplazamiento, el ciclo de ejecución está en UITrackingRunLoopMode. De forma predeterminada, NSURLConnection se programa solo en NSDefaultRunLoopMode, por lo que no recibirá ningún mensaje mientras se desplaza.

Así es como para programar la conexión en los modos "comunes", que incluye UITrackingRunLoopMode:

NSURLRequest *request = ... 
NSURLConnection *connection = [[NSURLConnection alloc] 
           initWithRequest:request 
           delegate:self 
           startImmediately:NO]; 
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] 
      forMode:NSRunLoopCommonModes]; 
[connection start]; 

Tenga en cuenta que usted tiene que especificar startImmediately:NO en el inicializador, que parece ir en contra de la documentación de Apple que sugiere puede cambiar los modos de ciclo de ejecución incluso después de que haya comenzado.

+1

¡Eres un genio! –

+0

Buen trabajo, esto me ayudó. Gracias – bandejapaisa

+0

funciona muy bien. Gracias por compartir, por cierto ¿hay algún efecto secundario de esto? – bneupaane

1

Debe leer en NSRunLoop. Sospecho que, durante el desplazamiento, el ciclo de ejecución se está ejecutando en NSEventTrackingRunLoopMode, y NSURLConnection no está incluido en ese modo. Probablemente pueda evitar esto llamando al scheduleInRunLoop de NSURLConnection: forMode :, para que la descarga pueda realizarse durante el desplazamiento.

Esto probablemente afectará el rendimiento de desplazamiento, que es probablemente la razón para el modo de ciclo de ejecución por separado en primer lugar. ¡Pero pruébalo y mira cómo se siente!

0

Primero ... su conexión probablemente ni siquiera está comenzando hasta que llegue al mainRunLoop y allí es donde también se está procesando la animación de desplazamiento.

Me encontré con el mismo problema y lo solucioné diciendo a las conexiones para que las imágenes comenzaran inmediatamente después de la creación.

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:wrapper.request delegate:wrapper]; 

    [connection start]; 

En la rutina de finalización en la que recibe la imagen y ajusta la cell.imageView.image a la imagen recibida, usted debe comprobar para ver si esta célula pertenece a una de las celdas que actualmente se muestran en la tabla. ..y si es así, llama a [tableView reloadData].

NSInteger itemIndex = theIndexInTheRowDataOfTheCellYouStuffedTheImage 

    NSArray *indicies = [_tableView indexPathsForVisibleRows]; 
    NSUInteger rows = indicies.count; 

    if (rows > 0 && 
     itemIndex >= ((NSIndexPath *)[indicies objectAtIndex:0]).row && 
     itemIndex <= ((NSIndexPath *)[indicies objectAtIndex:rows - 1]).row) 
    {  
     [_tableView reloadData]; 
    } 
1

Si envuelve su actualización de la imagen descarga & en un NSOperation, las actualizaciones va a pasar como la mesa con vista al rollos.

Otra ventaja de NSOperation es que puede cancelar la operación cuando la célula se desliza fuera de la pantalla. Se sentirá mucho más receptivo para el usuario ... especialmente si se desplazan rápidamente por una larga lista. La charla técnica de Apple este año alentó esta técnica.

Si sus listas no son tan largas, o si prefiere que continúen cargando, puede manipular las prioridades de NSOperation en su lugar.

+0

Originalmente diseñé mi código de esta manera y fue genial. Luego migré a Three20, que usa NSURLConnection y encontré el mismo problema que describió Brad. Voy a probar el inicio y ejecutar sugerencias de bucle a continuación. –