ios - uitableviewcontroller - uitableviewcell
UIRefreshControl endRefreshing no es suave (5)
Estoy agregando una nueva respuesta, ya que la única no es una explicación muy precisa. Y esto probablemente sería demasiado para comentarios.
La solución de es correcta. Pero la razón mencionada es incorrecta.
Llamando -[NSObject (NSDelayedPerforming) performSelector:withObject:afterDelay:]
garantiza que la llamada se realice en la siguiente iteración de bucle de ejecución.
Entonces, esto no funciona, porque hay un pequeño retraso, pero lo estás moviendo al siguiente ciclo.
En realidad, usted podría reducir el retardo a 0.0
y aún funcionaría. Además, es posible una implementación más correcta (en términos de uso del objeto destinado a lograr algo, no mejor en el resultado).
Aquí están los varios fragmentos de código para eso:
// SOLUTION I
[[self tableView] reloadData];
[[self refreshControl] performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.0];
// SOLUTION II (semantically correct)
[[self tableView] reloadData];
[[NSOperationQueue currentQueue] addOperationWithBlock:^{
[[self refreshControl] endRefreshing];
}];
// SOLUTION III (GCD)
dispatch_async(dispatch_get_main_queue(), ^{
[[self refreshControl] endRefreshing];
}];
EDITAR
Como señaló johann-fradj , también puedes usar GCD. Me gusta mucho el GCD, pero creo que la solución II es muy descriptiva sobre lo que está pasando. Además, GCD no es muy objetivo-C-ish, así que personalmente prefiero atenerme a mi solución.
Cuando mis datos han terminado de cargarse y mi tableView se ha vuelto a cargar, llamo a endRefreshing en mi control de actualización, luego ''salta'' de su estado de carga y desaparece. ¿Cómo puedo implementar una animación suave que retire el control de actualización cuando esté completa? ?
Intente endRefreshing()
la llamada a endRefreshing()
en un bloque de animación UIView:
También me he encontrado con este problema. Para endRefreshing()
La documentación indica:
UIView.animateWithDuration(0.5) {
self.refreshControl.endRefreshing()
}
La documentación establece:
Si las animaciones también están habilitadas, el control se oculta mediante una animación.
Se solucionó el problema: agregué un pequeño retraso a endRefresh después de volver a cargar los datos:
[self.tableView reloadData];
[self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.05];
Solución Swift 4
tableView.reloadData()
if refreshControl?.isRefreshing == true {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}
Otras soluciones (retraso, uso de CATransaction, ...) son más complejas y no dan ninguna ventaja visible
Una de las razones puede ser que actualice su vista de tabla después de llamar a endRefresh. Por ejemplo, mis llamadas solían verse así:
[self.refreshControl beginRefreshing];
[self.network getThings:^(id things, NSError *error) {
[self.refreshControl endRefreshing];
if (error) {
...
} else {
self.things = things;
[self.tableView reloadData];
}
}];
Lo que es malo, porque la tabla se actualiza a sí misma mientras se ejecuta la animación endRefresh. Así que el código hecho correctamente se ve así:
[self.refreshControl beginRefreshing];
[self.network getThings:^(id things, NSError *error) {
if (error) {
[self.refreshControl endRefreshing];
...
} else {
self.things = things;
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
}];