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.

example of the problem

21
demandé sur Senior 2015-06-29 16:51:46

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.

1
répondu Tom Hamming 2018-05-03 15:18:39
 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()
}
0
répondu Jože Ws 2017-05-19 10:58:11
  1. Set estimatedItemSize propriété à une certaine taille appropriée.

  2. 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
}
0
répondu dev gr 2017-08-11 06:16:05

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()
    }
0
répondu Mecid 2018-04-14 21:24:56