2010-02-23 15 views
24

Tengo una UITableview que cargué con datos asincrónicos para que la tabla vista pueda aparecer sin datos.
He agotado el método ReloadData pero la tabla permanece vacía hasta que me desplazo por la vista de tabla, de repente aparecen los datos.
Lo mismo ocurre cuando cargo una vista de tabla como una vista detallada y cambio entre elementos, los datos de elementos previos aparecen primero y tan pronto como me desplazo en la vista de tabla, se muestran los datos correctos.
Supongo que el método ReloadData funciona bien, pero tengo que volver a dibujar la tabla de alguna manera, ¿alguna sugerencia sobre cómo resolver esto?Redraw UITableView después de actualizar datos asincrónicos

/Jimmy

+0

Normalmente, el método reloadData actualiza la vista de la tabla. ¿Podría poner una muestra de su código TableViewController? –

Respuesta

53

Usted ha dicho que está poblando el contenido de forma asíncrona pero ¿invocar la reloadData en el contexto del hilo principal? (Y no a través de la rosca que puebla el contenido)

Objective-C

[yourUITableView performSelectorOnMainThread:@selector(reloadData) 
            withObject:nil 
           waitUntilDone:NO]; 

Swift

dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() }) 

MonoTouch

InvokeOnMainThread(() => this.TableView.ReloadData()); 
+7

Gracias que lo resolvió =) la solución para monotouch es: InvokeOnMainThread (() => this.TableView.ReloadData()); –

+0

@yonel Estoy teniendo el mismo problema que JimmyEngtröm y realmente estaba esperando que lo dijese que lo haría, pero todavía tengo este problema. No puedo encontrar ninguna manera de actualizar el UITableView después de actualizar las matrices de datos subyacentes que está utilizando. –

+0

@ MasonG.Zhwiti: establezca un punto de interrupción en su método numberOfRowsInSections en su origen de datos de tabla, y verifique si entra después de reloadData. Luego, verifique el número de filas que devuelve aquí, si no es 0, entonces llamará a cellForRowAtIndex. – yonel

2

Supongo que no se ha vuelto a cargar.

Cuando se desplaza a las células fuera de la pantalla, a continuación, ...

tableView: cellForRowAtIndexPath:

... se llamará. Entonces será recargado.

Supongo que la variable UITableView no está validada.

Si usa UITableView como vista principal, puede intentarlo.

[self.view reloadData];

o

[self.tableView reloadData];

4

Yonels respuesta es perfecta cuando su punto de vista es actualmente visible para el usuario (por ejemplo: El usuario pulsa un botón de recarga, que puebla su UITableView.)

Sin embargo, si los datos se carga de forma asíncrona y su UITableView no es visible durante la actualización (por ejemplo: agrega datos a su UITableView en otra vista y el UITableView se muestra más tarde por la entrada de usuario), simplemente anule el método UITableViewControllerviewWillAppear.

- (void)viewWillAppear:(BOOL)animated{ 
[super viewWillAppear:animated]; 
[self.tableView reloadData]; 
} 

El efecto positivo es que su UITableView solamente vuelve a cargar sus datos quedarán una vez cuando el usuario realmente quiere de lo vean, no cuando se añaden nuevos elementos.

2

Tuve el problema similar hoy (Storyboard en iOS 7.0). Estaba usando Table View dentro de un UIViewController. Cuando se cargó la vista, todo funcionaba bien; todos los delegados fueron llamados.Sin embargo ; Cuando el dataSource subyacente (en mi caso, Array) fue modificado; las filas de la tabla visible no se actualizaban. Se actualizaron; solo cuando estaba desplazando la vista de tabla.

Probé todo; llamando a reloadData en el hilo principal, llamando a recargar en ViewWillAppear; nada funcionó.

El problema que encontré; era que no había hecho la conexión en el guión gráfico; para la vista de tabla con el Outlet de referencia. Sin embargo, se establecieron el dataSource y el delegado. No pensé que podría ser el problema; ya que todo estaba funcionando bien en el primer intento.

Espero que ayude a alguien. Tuve un tiempo terrible para descubrirlo.

0

Después de copiar algo ingenuamente en la solución de yonel y llamarla bien, me di cuenta de que llamar al performSelectorOnMainThread:withObject:waitUntilDone: solucionó el síntoma, pero no el problema. El problema más grande es que está realizando actualizaciones de UI mientras aún está en el contexto del subproceso asincrónico o de fondo.

Esto es lo que mi código parecía:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 
    // Make a call to reload table data 

}); 

cuando debería tener este aspecto:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    // Now make the call to reload data and make any other UI updates 
    [self.tableView reloadData] 
    }); 

}); 

Si lo única lo que necesita hacer es llamar [self.tableView reloadData] es probablemente muy bien a use performSelectorOnMainThread:withObject:waitUntilDone: ya que logra el mismo objetivo, pero también debe reconocer lo que está sucediendo en el panorama general. Además, si está haciendo más trabajo de UI que simplemente volver a cargar la tabla, todo ese código debería ir también a la cola principal.

Referencia: A concise example de usar GCD y administrar el fondo frente al hilo principal.

Cuestiones relacionadas