He creado una UITableview con secciones en las que se puede hacer clic. Al hacer clic sobre ellos,insertRowsAtIndexPaths: con scrollToRowAtIndexPath: hace que las secciones de UITableView se oculten incorrectamente
- que "expanden" para revelar las células dentro de ellos
- los rollos sección click en la parte superior de la vista.
calculo todos los indexpaths a insertar/eliminar las células necesarias y luego insertarlos con el siguiente código:
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation];
[self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
Sólo hay un problema- están ocultos debajo de las secciones de la sección seleccionada. La primera captura de pantalla muestra cómo debe verse la tabla. La segunda captura de pantalla muestra cómo se ve realmente.
Si se desplaza hacia arriba (por lo que las secciones ocultas son fuera de la pantalla) y luego se desplaza hacia abajo, las secciones ocultas son llevados de vuelta (una vez más visible). Mi suposición de por qué esto está sucediendo es la siguiente:
Las animaciones de inserción/eliminación están sucediendo al mismo tiempo que el scrollToRowAtIndexPath
y confunde el TableView. Si no hubiera hecho scrollToRowAtIndexPath
secciones 3 & 4 habría sido fuera de pantalla, por lo que el tableView de alguna manera todavía piensa que son fuera de la pantalla. UITableview oculta celdas/secciones que están fuera de pantalla como una optimización. Si llamo al scrollToRowAtIndexPath
con un dispatch_after
con 2 segundos, las secciones 3 & 4 se muestran correctamente.
Así que creo que sé por qué ocurre esto, pero no sé cómo corregir/anular esta optimización de UITableview. En realidad, si implemento scrollViewDidEndScrollingAnimation
y luego agrego un punto de interrupción en esta función, la aplicación muestra las secciones 3 & 4 correctamente (así es como obtuve la primera captura de pantalla). Pero una vez que continúa desde esta función, las células desaparecen.
El proyecto completo se puede descargar here
detalles de implementación adicionales: Las secciones son secciones UITableView legítimos. He agregado un tapGestureRecognizer que desencadena una devolución de llamada de delegado a la vista de tabla. A continuación se incluye todo el método que abre las secciones.
- (void)sectionHeaderView:(SectionHeaderView *)sectionHeaderView sectionOpened:(NSInteger)sectionOpened
{
// Open
sectionHeaderView.numRows = DefaultNumRows;
sectionHeaderView.selected = YES;
NSMutableArray *pathsToOpen = [[NSMutableArray alloc] init];
for (int i = 0; i < sectionHeaderView.numRows; i++)
{
NSIndexPath *pathToOpen = [NSIndexPath indexPathForRow:i inSection:sectionOpened];
[pathsToOpen addObject:pathToOpen];
}
// Close
NSMutableArray *pathsToClose = [[NSMutableArray alloc] init];
if (openSectionHeader)
{
for (int i = 0; i < openSectionHeader.numRows; i++)
{
NSIndexPath *pathToClose = [NSIndexPath indexPathForRow:i inSection:openSectionHeader.section];
[pathsToClose addObject:pathToClose];
}
}
// Set Correct Animation if section's already open
UITableViewRowAnimation insertAnimation = UITableViewRowAnimationBottom;
UITableViewRowAnimation deleteAnimation = UITableViewRowAnimationTop;
if (!openSectionHeader || sectionOpened < openSectionHeader.section)
{
insertAnimation = UITableViewRowAnimationTop;
deleteAnimation = UITableViewRowAnimationBottom;
}
openSectionHeader.numRows = 0;
openSectionHeader.selected = NO;
openSectionHeader = sectionHeaderView;
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation];
[self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
Creo que será mejor que utilices el MVC provisto por Apple. Todo lo que tiene que hacer es agregar/eliminar datos en su origen de datos y no tocar las filas de la vista de tabla – divol
Incluya un poco más de su proyecto en la pregunta, en lugar de esperar una descarga; por ejemplo, cómo calcula las rutas de índice para agregar/eliminar, y son sus encabezados de sección de cosas de "Sección X" o solo son celdas? Sería una mejor pregunta independiente si no dependiera tanto de la descarga de su proyecto. – jrturton
Creo que tu suposición es correcta también. ¿Puedes intentar volver a cargar las filas en el método de delegado de scroll ended? – jrturton