ios objective-c uicollectionview contentsize contentoffset

Animación de cambios contentOffset en un UICollectionView en deleteItemsAtIndexPaths



objective-c contentsize (1)

Tengo un UICollectionView al que se pueden agregar y eliminar celdas. Estoy haciendo estos cambios utilizando performBatchUpdates , y el diseño se está animando como se esperaba.

El problema surge cuando me desplazo hasta el final del contenido y elimino un elemento de tal forma que el tamaño del contentSize disminuye: Esto hace que el contentSize contentOffset cambie, pero el cambio no está animado. En cambio, contentOffset salta inmediatamente después de que se completa la animación de eliminación. Intenté actualizar manualmente contentOffset junto con la eliminación, pero tampoco me funcionó.

Estoy usando un diseño personalizado, pero veo el mismo comportamiento con un diseño de flujo estándar, usando 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 tiene perplejo.


El error de animación se observa cuando el contentSize del contentSize de la vista de colección se reduce de tal manera que su altura o ancho se vuelve más pequeño que (o igual) al de los límites de la vista de colección.

Es posible forzar la animación esperada en el bloque de actualización por lotes usando setContentOffset:animated: y similar, pero esto depende de conocer el tamaño del contenido proyectado después de la eliminación. El tamaño de contenido es administrado por el diseño de la vista de colección, pero como todavía no hemos eliminado la celda, no podemos simplemente pedir el diseño (o obtendríamos el tamaño anterior).

Para targetContentOffsetForProposedContentOffset: este problema, implementé el método targetContentOffsetForProposedContentOffset: en mi diseño personalizado para ajustar el desplazamiento del contenido como lo deseaba. El código a continuación, que solo tiene en cuenta el desplazamiento 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; }

Intenté esto en una subclase UICollectionViewFlowLayout directa y también hace el trabajo allí.