2011-02-11 11 views
7

Tengo una UITableView con una lista de elementos, cada uno con su propia imagen. Pensé que el proyecto de muestra LazyTableImages de Apple sería perfecto para aprender y utilizar para implementar el mismo tipo de proceso de descarga de imágenes de manera asincrónica, una vez recuperados los datos de la lista original.Pregunta sobre el ejemplo de LazyTableImages de Apple: no se comporta exactamente como en la tienda de aplicaciones

En general, funciona bastante bien, excepto que noté una sutil diferencia de comportamiento entre esta aplicación de muestra y cómo la tienda de aplicaciones actual descarga imágenes.

Si inicia el ejemplo de LazyTableImages, haga un rápido deslizamiento hacia abajo, verá que las imágenes no se muestran hasta después de el desplazamiento se detiene por completo.

Ahora, si realiza la misma prueba con una lista de elementos en la tienda de aplicaciones real, verá que las imágenes comienzan a mostrarse tan pronto como aparecen los nuevos elementos, incluso si el desplazamiento no se ha detenido todavía .

Estoy tratando de lograr los mismos resultados, pero hasta ahora no estoy progresando. ¿Alguien tiene alguna idea sobre cómo hacer esto?

Gracias!

Respuesta

10

estoy desconcertado que nadie podía responder a esta ...

Así, al final me di cuenta de cómo acheive la exacta mismo efecto que se utiliza en la tienda de aplicaciones reales, en lo que respecta a cómo los iconos se descargan/muestran.

Tome el proyecto de ejemplo LazyTableImages y realice algunas modificaciones simples.

  1. entrar en el controlador de vista raíz y eliminar todos los controles relativos a es el desplazamiento de mesa y/o deceleración en cellForRowAtIndexPath

  2. Retire todas las llamadas a loadImagesForOnScreenRows, y por lo tanto eliminar ese método, así.

  3. Id a IconDownload.m y cambiar el método de startDownload a no hacer una imagen downlaod asíncrono, pero en su lugar hacer una descarga de sincronización en un subproceso de fondo.Eliminar todo el código en startDownload, y añadir lo siguiente, por lo que se ve así:

 

- (void)startDownload 
{ 
    NSOperationQueue *queue = [NSOperationQueue new]; 
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImage) object:nil]; 

    [queue addOperation:operation]; 

    [operation release]; 
    [queue release]; 
} 
 

A continuación, añadir un loadImage, así:

 

- (void)loadImage 
{ 
    NSData *imageData = [[NSData alloc] initWithContents OfURL:[NSURL URLWithString:appRecord.imageURLString]]; 
    self.apprecord.appIcon = [UIImage imageWithData:imageData]; 
    [imageData release]; 

    [self performSelectorOnMainThread:@selector(notifyMainThread) withObject:nil waitUntilDone:NO]; 
} 
 

A continuación, añadir notifyMainThread como esto :

 

- (void)notifyMainThread 
{ 
    [delegate appImageDidLoad:self.indexPathInTableView]; 
} 
 

¡Hecho! Ejecútelo, verá el comportamiento exacto de la tienda de aplicaciones, no tendrá que esperar para solicitar descargas de imágenes hasta que se detenga el desplazamiento, y no más esperar a que se muestren las imágenes hasta que el desplazamiento se detenga o hasta que el usuario haya quitado el dedo de la pantalla.

Las imágenes se descargan tan pronto como la célula está lista para visualizarse, y la imagen se visualiza tan pronto como se descarga, punto.

Lo siento por ninguna errata, no me pego esto desde mi aplicación, he escrito en ella, ya que estoy lejos de mi mac en este momento ...

De todos modos, espero que esto le ayuda a todos. ..

+0

¡Brillante! ¡Gracias por publicar esto! –

+0

Aprecio tu esfuerzo para mejorar el ejemplo de Apple. Tu solución funciona en parte. Los delegados de desplazamiento deben ** NO ** ser eliminados, o su controlador de vista no sabe cuándo comenzar a descargar los íconos. El 'loadImagesForOnScreenRows' también se debe llamar en' viewDidLoad' o 'viewDidAppear', depende del uso. – Raptor

+0

Bueno, pero cambia todo el código de muestra. Ya no usa NSURLConnection. – yosh

0

Consulte UIScrollViewDelegate. Implementé algo así escuchando scrollViewDidScroll:, calculando la velocidad de desplazamiento (marcando contentOffset contra el último contentOffset registrado, dividido por la diferencia en el tiempo) y comenzando a cargar imágenes una vez que la velocidad cae por debajo de un cierto umbral. (Usted podría lograr algo similar con UIScrollViewDelegate's scrollViewDidEndDragging:willDecelerate: también).

Por supuesto, no tiene que verificar la velocidad; solo podría cargar imágenes en UITableViewDelegate 's tableView:willDisplayCell:forRowAtIndexPath: cada vez que vea una nueva celda, pero he descubierto que si el usuario está hojeando toneladas de células, no necesita molestarse hasta que vea que van a ralentizar abajo para navegar

+0

He intentado esto. He verificado que las llamadas para descargar las imágenes del elemento recién visualizadas están sucediendo inmediatamente. Sin embargo, connectionDidFinishLoading: nunca se llama hasta que el desplazamiento se detiene por completo. Estoy realmente confundido por este comportamiento ... – bpatrick100

+0

Otra forma de describir el comportamiento de la aplicación de ejemplo, es si desliza la lista hacia arriba, pero no suelta el dedo (guárdelo en la pantalla), verá que el las imágenes no se muestran. Luego, tan pronto como suelte su dedo, se mostrarán las imágenes. Parece un comportamiento de subproceso único. Me pregunto si ese es todo el problema aquí. Me pregunto si tengo que colocar explícitamente cada una de las llamadas de descarga de imágenes en su propio hilo ... – bpatrick100

+0

Debería bastar con asignar un hilo para todas sus llamadas de descarga. En cuanto a las conexiones en general, recomendaría ASIHTTPRequest (http://allseeing-i.com/ASIHTTPRequest/) – kevboh

Cuestiones relacionadas