uicollectionviewflowlayoutautomaticsize uicollectionviewdelegateflowlayout systemlayoutsizefitting collection automatic ios ios8 autolayout uicollectionview

ios - systemlayoutsizefitting - uicollectionviewdelegateflowlayout



UICollectionView con celdas de auto-tamaño cambia el tamaño de las celdas durante la inserción/remueve animación (4)

  1. Establezca el valor estimatedItemSize propiedad en un tamaño apropiado.

  2. En tu clase UICollectionView personalizada, anula debajo del método y el tamaño de la memoria caché layoutAttributes dado por super.

    -(UICollectionViewLayoutAttributes*)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { UICollectionViewLayoutAttributes * superAttr = [super preferredLayoutAttributesFittingAttributes:layoutAttributes]; //Cache size which is returned by super (superAttr.frame.size) since super calculates the correct size for auto size cells. return superAttr; }

3.En sizeForItemAtIndexPath devuelve el tamaño en caché si está disponible en otro tamaño estimado.

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { //return cached size if available else the estimated size }

Tengo un UICollectionView simple con un UICollectionViewFlowLayout que usa autolayout para permitir el tamaño de las celdas. Las cosas funcionan bien en un diseño estático, pero cuando inserto o elimino celdas, las celdas cambian de tamaño al tamaño estimado:

[self.collectionView performBatchUpdates:^{ [self.collectionView insertItemsAtIndexPaths:@[indexPath]]; } completion:nil];

Más allá de establecer el tamaño estimado, así:

layout.estimatedItemSize = CGSizeMake(88.0, 88.0);

No estoy haciendo nada lujoso en la vista de colección. Todo está configurado utilizando guiones gráficos.

¿Cómo puedo evitar este cambio de tamaño? Solo estoy apuntando a iOS 8.0 y superior, por lo que debería ser compatible.


Me encontré con esto, y me tomó un tiempo darme cuenta de que el tamaño al que estaba volviendo era el tamaño estimado.

Creo que encontré una solución:

  • Mantenga una instancia de su clase de celda de auto-tamaño alrededor
  • Implemente sizeForItemAtIndexPath y configure esa instancia de celda con datos para esa ruta de índice, luego pregúntele cuál es su tamaño preferido ( systemLayoutFittingSize ).
  • Guarda esta información en un diccionario para mejorar el rendimiento.

Ver proyecto de ejemplo here .


Para evitar el cambio de tamaño de celda use InvalidationContext

let context = UICollectionViewFlowLayoutInvalidationContext() context.invalidateFlowLayoutAttributes = false collectionView.collectionViewLayout.invalidateLayout(with: context) UIView.animate(withDuration: 0.3) { self.collectionView.layoutIfNeeded() }


Una solución directa es implementar el método UICollectionViewDelegateFlowLayout

func collectionView(_ collectionView: UICollectionView, layoutcollectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // calculate string size here }

Y después de insertar o eliminar celdas, asegúrese de invalidar el diseño para que se llame nuevamente al método de delegado

collectionView.performBatchUpdates({ // insert/delete items here }) { (success: Bool) in collectionView.collectionViewLayout.invalidateLayout() }