ios - how - UICollectionView cambio de datos animados
uicollectionview swift 4 (8)
El texto de ayuda dice:
Llame a este método para volver a cargar todos los artículos en la vista de colección. Esto hace que la vista de colección descarte los elementos actualmente visibles y los vuelva a mostrar. Para mayor eficiencia, la vista de colección solo muestra aquellas celdas y vistas suplementarias que son visibles. Si los datos de recopilación se reducen como resultado de la recarga, la vista de recopilación ajusta sus desplazamientos de desplazamiento en consecuencia. No debe llamar a este método en el medio de bloques de animación donde se insertan o eliminan elementos. Las inserciones y eliminaciones hacen que los datos de la tabla se actualicen de forma adecuada.
Creo que la parte clave es "hace que la vista de colección descarte los elementos actualmente visibles". ¿Cómo va a animar el movimiento de los artículos que ha descartado?
En mi proyecto uso UICollectionView para mostrar una grilla de iconos.
El usuario puede cambiar el orden haciendo clic en un control segmentado que llama a una recuperación desde los datos centrales con diferentes NSSortDescriptor.
La cantidad de datos siempre es la misma, terminando en diferentes secciones / filas:
- (IBAction)sortSegmentedControlChanged:(id)sender {
_fetchedResultsController = nil;
_fetchedResultsController = [self newFetchResultsControllerForSort];
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
[self.collectionView reloadData];
}
El problema es que ReloadData no anima el cambio, UICollectionView simplemente aparece con los nuevos datos.
¿Debo hacer un seguimiento en qué indexPath una celda estaba antes y después del cambio, y usar [self.collectionView moveItemAtIndexPath: toIndexPath:] para realizar la animación para el cambio o hay un método mejor?
No me interesaba mucho la subclasificación de collectionViews, así que cualquier ayuda será genial ...
Gracias, Bill.
Envoltura -reloadData
en -performBatchUpdates:
no parece causar una vista de colección de una sola sección para animar.
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:nil];
Sin embargo, este código funciona:
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
Esto es lo que hice para animar la recarga de TODAS LAS SECCIONES:
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];
Swift 3
let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
let indexSet = IndexSet(integersIn: range)
collectionView.reloadSections(indexSet)
Para los usuarios de Swift, si su vista de colección solo tiene una sección:
self.collectionView.performBatchUpdates({
let indexSet = IndexSet(integersIn: 0...0)
self.collectionView.reloadSections(indexSet)
}, completion: nil)
Como se ve en https://.com/a/42001389/4455570
Para usuarios rápidos, esto es útil:
collectionView.performBatchUpdates({
self.collectionView.reloadSections(NSIndexSet(index: index))
}, completion: nil)
Recargar toda la vista de colección dentro de un performBatchUpdates:completion:
bloque hace una animación glitchy para mí en el simulador de iOS 9. Si tiene un UICollectionViewCell
específico que desea eliminar, o si tiene su ruta de índice, puede llamar a deleteItemsAtIndexPaths:
en ese bloque. Al usar deleteItemsAtIndexPaths:
hace una animación suave y agradable.
UICollectionViewCell* cellToDelete = /* ... */;
NSIndexPath* indexPathToDelete = /* ... */;
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
// or...
[self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];
Si desea más control y características personalizables, consulte this , contiene una explicación muy detallada de las diversas formas de las animaciones UICollectionViewCell.
reloadData no se anima, ni lo hace confiablemente cuando se coloca en un bloque de animación UIView. Quiere estar en un bloque UICollecitonView performBatchUpdates, así que intente algo más como:
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:^(BOOL finished) {}];