Animación de los cambios de ContentOffset en un UICollectionView en deleteItemsAtIndexPaths

Tengo una UICollectionView a la que se pueden agregar y eliminar celdas. Estoy haciendo estos cambios usando performBatchUpdates , y el layout se está animando como se esperaba.

El problema viene cuando me desploop hasta el final del contenido y elimino un elemento de tal forma que el contentSize disminuye: Esto hace que el contentOffset cambie, pero el cambio no está animado. En lugar de eso, el contentOffset la contentOffset salta inmediatamente después de que se completa la animation de eliminación. Intenté actualizar manualmente el contentOffset del contentOffset junto con la eliminación, pero eso tampoco funcionó para mí.

Estoy usando un layout personalizado, pero veo el mismo comportamiento con un layout de flujo estándar, utilizando el siguiente código:

 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.items.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; UILabel *label = (UILabel *)[cell viewWithTag:1]; label.text = [self.items objectAtIndex:indexPath.item]; return cell; } - (IBAction)addItem:(UIBarButtonItem *)sender { self.runningCount++; [self.items addObject:[NSString stringWithFormat:@"Item %u",self.runningCount]]; [self.collectionView performBatchUpdates:^{ [self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:self.items.count-1 inSection:0]]]; } completion:nil]; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { [self.items removeObjectAtIndex:indexPath.item]; [self.collectionView performBatchUpdates:^{ [self.collectionView deleteItemsAtIndexPaths:@[indexPath]]; } completion:nil]; } 

Siento que debo estar perdiendo algo obvio, pero esto me deja perplejo.

Se ve la falla de animation donde el contentSize de la vista de la colección se networkinguce de tal manera que su altura o ancho se vuelve más pequeño que (o igual a) el de los límites de la vista de la colección.

Es posible forzar la animation esperada en el bloque de actualización por lotes usando setContentOffset:animated: y similar, pero esto depende de conocer el tamaño de contenido proyectado después de la eliminación. El tamaño de contenido está gestionado por el layout de la vista de colección, pero dado que aún no hemos eliminado la celda, no podemos simplemente pedir el layout (o obtendríamos el tamaño anterior).

Para evitar esto, implementé el método targetContentOffsetForProposedContentOffset: en mi layout personalizado para ajustar el desplazamiento de contenido como se desee. El código a continuación, que solo representa la compensación de Y, fue suficiente para mis necesidades:

 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset { if (self.collectionViewContentSize.height <= self.collectionView.bounds.size.height) { return CGPointMake(proposedContentOffset.x,0); } return proposedContentOffset; } 

Probé esto en una subclass directa UICollectionViewFlowLayout y hace el trabajo allí también.