Representación diferida de UIImageView en UITableView


Ok, tengo un UITableView con UITableViewCell s personalizados que cada uno contiene un UIImageView cuyas imágenes se están descargando asincrónicamente a través de un NSURLConnection. Todas cosas bastante estándar...

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

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

UPDATE ACTUALIZAR {

Después de una mirada más cercana, estoy encontrando que el NSURLConnection los métodos de delegado no se activan hasta que la tabla deja de desplazarse. No sé por qué. Cualquier ayuda sería genial.

Author: Brad, 2009-12-01

4 answers

La razón por la que los mensajes del delegado de conexión no se activan hasta que se detiene el desplazamiento se debe a que durante el desplazamiento, el bucle de ejecución está en UITrackingRunLoopMode. De forma predeterminada, NSURLConnection se programa solo en NSDefaultRunLoopMode, por lo que no recibe ningún mensaje mientras se desplaza.

He aquí cómo 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 debe especificar startImmediately:NO en el inicializador, que parece correr en contra de la documentación de Apple que sugiere que puede cambiar la ejecución modos de bucle incluso después de que haya comenzado.

 65
Author: Daniel Dickison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-03 15:45:16

Deberías leer sobre NSRunLoop. Sospecho que, durante el desplazamiento, el bucle de ejecución se está ejecutando en NSEventTrackingRunLoopMode, y el NSURLConnection no está incluido en ese modo. Probablemente podría evitar esto llamando a scheduleInRunLoop:forMode: de NSURLConnection, para que la descarga pueda ocurrir durante el desplazamiento.

Esto probablemente afectará el rendimiento del desplazamiento, que es probablemente la razón para el modo de bucle de ejecución separado en primer lugar. Pero pruébelo y vea cómo siente!

 1
Author: benzado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-01 20:30:39

Si envasa la descarga y actualización de su imagen en un NSOperation, las actualizaciones se realizarán como desplazamiento de la vista de tabla.

Otro beneficio de NSOperation, es que puede cancelar la operación a medida que la celda se desliza fuera de la pantalla. Se sentirá mucho más sensible al usuario.. especialmente si desplazan una larga lista rápidamente. La Apple tech-talk de este año alentó esta técnica.

Si sus listas no son tan largas, o prefiere que continúen cargándose, puede manipular el Prioridades de NSOperation en su lugar.

 1
Author: ohhorob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-07 19:41:07

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

Me encontré con el mismo problema y lo arreglé diciendo que las conexiones para 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 donde recibe la imagen y establece la celda.ImageView.imagen a la imagen recibida, debe verificar si esta celda pertenece a una de las celdas que se encuentran actualmente se muestra en la tabla...y si es así llame 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];
    }
 0
Author: captain cosmic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-02 23:47:50