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)
Establezca el valor
estimatedItemSize
propiedad en un tamaño apropiado.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()
}