2009-12-01 4 views
27

Ok, ho uno UITableView con personalizzato UITableViewCell s ciascuno contenente uno UIImageView le cui immagini vengono scaricate in modo asincrono tramite un NSURLConnection. Tutto roba piuttosto standard ...Rappresentazione UIImageView ritardata in UITableView

Il problema è che quando le tabelle scorrono, le nuove immagini vengono scaricate correttamente sullo sfondo ma non vengono restituite fino a quando il tavolo non si ferma.

Come si ottiene la tabella per renderne il contenuto anche quando è in movimento? Grazie.

- AGGIORNAMENTO -

Dopo uno sguardo più attento, ho constatato che le NSURLConnection metodi delegato non stanno sparando fino al tavolo smette di scorrere. Non so perché. Qualsiasi aiuto sarebbe grande.

risposta

65

Il motivo per cui i messaggi di delega della connessione non vengono attivati ​​finché non si interrompe lo scorrimento è perché durante lo scorrimento, il ciclo di esecuzione è UITrackingRunLoopMode. Per impostazione predefinita, NSURLConnection si programma solo nel NSDefaultRunLoopMode, quindi non si ottiene alcun messaggio durante lo scorrimento.

Ecco come pianificare la connessione in modalità "comuni", che comprende UITrackingRunLoopMode:

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

Si noti che è necessario specificare startImmediately:NO nel inizializzatore, che sembra in contrasto con la documentazione di Apple che si suggerisce può cambiare le modalità del ciclo di esecuzione anche dopo l'avvio.

+1

Sei un genio! –

+0

Bel lavoro - questo mi ha aiutato. Grazie – bandejapaisa

+0

funziona bene. Grazie per la condivisione, perché c'è qualche effetto collaterale di questo? – bneupaane

1

Si consiglia di leggere su NSRunLoop. Sospetto che, durante lo scorrimento, il ciclo di esecuzione sia eseguito in NSEventTrackingRunLoopMode e NSURLConnection non è incluso in quella modalità. Probabilmente è possibile aggirare questo problema chiamando la pianificazione di NSURLConnectionInRunLoop: forMode :, in modo che il download possa avvenire durante lo scorrimento.

Questo probabilmente influirà sulle prestazioni di scorrimento, che è probabilmente il motivo della modalità di ciclo di esecuzione separata in primo luogo. Ma provalo e guarda come ci si sente!

0

Per prima cosa ... la tua connessione probabilmente non si avvia nemmeno fino a quando non arriva al mainRunLoop ed è qui che viene elaborata anche l'animazione a scorrimento.

Mi sono imbattuto nello stesso problema e l'ho risolto dicendo che le connessioni per le immagini iniziarono immediatamente dopo la creazione.

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

    [connection start]; 

Nella routine di completamento in cui si riceve l'immagine e si imposta la cell.imageView.image per l'immagine ricevuta, si dovrebbe controllare per vedere se questa cellula appartiene a una delle celle attualmente in fase di visualizzati nella tabella. ..e in questo caso chiama [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

Se si avvolgono l'aggiornamento image scaricare & in un NSOperation, gli aggiornamenti accadrà come i rotoli tavolo con vista.

Un altro vantaggio di NSOperation è che è possibile annullare l'operazione mentre la cella scorre fuori dallo schermo. Si sentirà molto più reattivo per l'utente .. soprattutto se scorrerà rapidamente una lunga lista. Il tech-talk di Apple quest'anno ha incoraggiato questa tecnica.

Se le tue liste non sono così lunghe, o preferiresti che continuassero a caricare, puoi invece manipolare le priorità NSOperation.

+0

Originariamente ho progettato il mio codice in questo modo ed è stato fantastico. Poi sono migrato su Three20, che utilizza NSURLConnection e mi sono imbattuto nello stesso identico problema descritto da Brad. Proverò all'inizio e eseguirò i suggerimenti del ciclo di seguito. –