iphone - human - ios design rules
guardar la fila seleccionada en UITableView después de reloadData (9)
Añadiendo un poco a la respuesta de Marco:
Primero, si está utilizando una selección múltiple , puede agregar este método a su ViewController
y llamarlo siempre que necesite llamar a [tableView reloadData]
:
- (void)reloadTableView
{
NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
[self.tableView reloadData];
for (NSIndexPath *path in indexPaths) {
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
En segundo lugar, si está en un UITableViewController
y desea conservar la selección después de que aparezca tableView, existe una función en UITableViewController: clearsSelectionOnViewWillAppear
puede clearsSelectionOnViewWillAppear
o desactivarse.
Escribo cliente de jabber personalizado en iphone.
Yo uso xmppframework como motor.
Y tengo UITableViewController con NSMutableArray para la lista de contactos representados.
Cuando recibo (o alguien lo cambia el contenido) la lista (también conocida como lista de contactos) quiero cambiar los elementos de UITableView (agregar / eliminar / modificar). Entonces, si el usuario trabaja con listView en el momento cuando la lista se actualice por
[items addObject:newItem];
[self.tableView reloadData];
el usuario perdió el elemento de selección actual.
Por lo tanto, mi pregunta es cómo guardar (si es posible, me refiero a si el elemento seleccionado no se elimina) elemento de selección actual después de reloadData?
Gracias.
Agregar un retraso no funcionó para mí (probado en iOS 8.4 e iOS 9). Lo que funcionó fue agregar una llamada a -layoutIfNeeded
en la celda seleccionada, después de llamar a -selectRowAtIndexPath:animated:scrollPosition:
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
[self.tableView reloadData];
[self.tableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[[self.tableView cellForRowAtIndexPath:selectedIndexPath] layoutIfNeeded];
En iOS 9.3 y Swift 2.x, simplemente tuve que llamar a la función en el hilo principal :)
self.tableView?.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
Esta es una solución para el caso si desea hacer actualizaciones de tablas y mantener la selección:
NSIndexPath* pathToSelect = [self.tableView indexPathForSelectedRow];
if (pathToSelect && newRows) {
int row = pathToSelect.row;
for (NSIndexPath* path in newRows) {
if (path.section == pathToSelect.section && path.row <= pathToSelect.row) {
row++;
}
}
pathToSelect = [NSIndexPath indexPathForRow:row inSection:pathToSelect.section];
}
[self.tableView beginUpdates];
if (reloadRows) [self.tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation:UITableViewRowAnimationFade];
if (newSections) [self.tableView insertSections:newSections withRowAnimation:UITableViewRowAnimationFade];
if (newRows) [self.tableView insertRowsAtIndexPaths:newRows withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
if (pathToSelect) {
[self.tableView selectRowAtIndexPath:pathToSelect animated:NO scrollPosition:UITableViewScrollPositionNone];
}
Esto funciona para mí:
NSIndexPath *indexPath = [table indexPathForSelectedRow];
[table reloadData];
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.table selectRowAtIndexPath:indexPath animated:YES
scrollPosition:UITableViewScrollPositionNone];
});
El truco es hacer que selectRowAtIndexpath se ejecute un poco más tarde. El código anterior es una plantilla de Xcode que puede seleccionar cuando comience a escribir dispatch_after
.
La manera fácil es algo como esto:
NSIndexPath *ipath = [self.tableView indexPathForSelectedRow];
[self.tableView reloadData];
[self.tableView selectRowAtIndexPath:ipath animated:NO scrollPosition:UITableViewScrollPositionNone];
La solución alternativa es usar reloadSections: en lugar de reloadData. Por algún motivo, reloadData elimina la selección actual.
Parece que no está utilizando un ''modelo'' para los datos, simplemente está actualizando la ''vista'' (interfaz de usuario), y probablemente sea un mal diseño.
ReloadData debe hacer que la vista se actualice con los datos del modelo, que debe contener la información más reciente que se mostrará.
buscar recursos en el ''patrón de controlador de vista modelo''
SWIFT 3 :
self.collectionView.reloadData()
self.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])