UICollectionView with self-sizing cells redimensionne les cellules pendant l'animation insert/remove
j'ai un UICollectionView simple avec un UICollectionViewFlowLayout qui utilise l'autolayout pour permettre aux cellules de s'auto-dimensionner. Les choses fonctionnent bien dans une disposition statique, mais quand j'insère ou enlève des cellules, les cellules redimensionnent à la taille estimée:
[self.collectionView performBatchUpdates:^{
[self.collectionView insertItemsAtIndexPaths:@[indexPath]];
} completion:nil];
au-Delà de réglage de la taille estimée, comme ceci:
layout.estimatedItemSize = CGSizeMake(88.0, 88.0);
Je ne fais rien de fantaisiste dans la vue collection. Tout est mis en place à l'aide de story-boards.
Comment puis-je éviter ce redimensionnement? Je ne suis cibler iOS 8.0 et plus afin qu'il soit soutenu.
4 réponses
j'ai rencontré ça, et ça m'a pris un moment pour comprendre que la taille à laquelle il était retourné était la taille estimée.
je crois que j'ai trouvé une solution:
- conservez une instance de votre classe de cellules auto-dimensionnée autour de
- implémenter
sizeForItemAtIndexPath
, et configurer cette instance de la cellule avec les données pour ce chemin d'index, puis lui demander sa taille préférée (systemLayoutFittingSize
). - Cache cette information dans un dictionnaire performance.
Voir l'exemple du projet ici.
func collectionView(_ collectionView: UICollectionView, layoutcollectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// calculate string size here
}
et après avoir inséré ou supprimé des cellules assurez-vous d'invalider layout pour que la méthode delegate soit appelée à nouveau
collectionView.performBatchUpdates({
// insert/delete items here
}) { (success: Bool) in
collectionView.collectionViewLayout.invalidateLayout()
}
Set
estimatedItemSize
propriété à une certaine taille appropriée.Dans votre personnalisé
UICollectionView
classe remplacer méthode ci-dessous et cache layoutAttributes de la taille donnée par 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.In size foritematindexpath return cached size available else estimated size.
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
//return cached size if available else the estimated size
}
pour éviter de redimensionner la cellule, utilisez InvalidationContext
let context = UICollectionViewFlowLayoutInvalidationContext()
context.invalidateFlowLayoutAttributes = false
collectionView.collectionViewLayout.invalidateLayout(with: context)
UIView.animate(withDuration: 0.3) {
self.collectionView.layoutIfNeeded()
}