La modification de la taille de cellule en cours UICollectionView provoque un comportement indésirable

J’ai un UICollectionViewController qui utilise un UICollectionViewFlowLayout standard pour afficher une seule colonne verticale de cellules. Je tente de créer une animation d’extension / réduction sur une cellule lorsqu’une cellule est exploitée. J’utilise le code suivant pour accomplir ceci:

 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath (NSIndexPath *)indexPath { [self.feedManager setCurrentlySelectedCellIndex:indexPath.item]; [self.collectionView performBatchUpdates:nil completion:nil]; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { //Return the size of each cell to draw CGSize cellSize = (CGSize) { .width = 320, .height = [self.feedManager heightForCellAtIndexPath:indexPath] }; return cellSize; } 

La propriété ‘selectedCellIndex’ sur mon object de gestion indique au modèle de données de renvoyer une taille étendue ou réduite à l’intérieur de heightForCellAtIndexpath:

 [self.collectionView performBatchUpdates:nil completion:nil]; 

Ensuite, la performBatchUpdates:completiong: anime cette modification de taille. Toutefois! Lorsque l’animation se produit, la cellule en expansion peut faire disparaître une cellule partiellement visible au bas de l’écran.

Si tel est le cas et que, par la suite, cette cellule est réduite, la cellule maintenant hors écran se calera sur son ancienne position sans animation, alors que toutes les autres cellules visibles s’animeront comme vous le souhaitez. Mon intuition dit que c’est le comportement correct puisque la cellule est éteinte lorsque l’animation de réduction est en cours d’exécution et qu’elle n’est pas incluse dans le processus de rendu de l’animation. Ma question devient, comment puis-je empêcher cela?

Je préférerais que toutes les cellules s’animent ensemble, qu’elles soient hors écran ou non. Des pensées?

Ceci est un bogue UICollectionViewFlowLayout , mais il existe une solution de contournement. Le problème est que les atsortingbuts renvoyés par initialLayoutAtsortingbutesForAppearingItemAtIndexPath: ont les mauvais frameworks. Plus précisément, ils ont les frameworks de la position finale, à l’écran plutôt que la position initiale hors écran. Il vous suffit de remplacer cette méthode et de renvoyer les frameworks corrects. La structure de base de la substitution ressemblerait à ceci:

 - (UICollectionViewLayoutAtsortingbutes *)initialLayoutAtsortingbutesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath { UICollectionViewLayoutAtsortingbutes *pose = [super initialLayoutAtsortingbutesForAppearingItemAtIndexPath:itemIndexPath]; if () { CGRect frame = pose.frame; frame.origin.y = ; pose.frame = frame; } return pose; } 

Vous serez responsable de l’identification des scénarios dans lesquels les frameworks doivent être ajustés, ce qui peut impliquer de conserver votre propre état interne. Je n’ai pas travaillé sur cette logique, mais j’ai fait un test grossier et j’ai pu obtenir une animation fluide.

Généraliser un peu, c’est mon expérience que UICollectionViewFlowLayout est tellement UICollectionViewFlowLayout et qu’il ya tellement de cas particuliers à gérer si vous avez des éléments qui UICollectionViewFlowLayout et s’ajoutent à des insertions, suppressions ou déplacements que j’ai trouvés. il est plus facile de rouler mes propres mises en page simples. Si vous ne comptez pas effectuer d’insertions, de suppressions ou de déplacements, il peut être préférable de UICollectionViewFlowLayout .

Faites-moi savoir si vous avez besoin de plus d’aide.

MODIFIER

Si vous êtes intéressé par une mise en page à trois parties, j’ouvre la grid source personnalisée VCollectionViewGridLayout et j’ajoute un exemple de projet démontrant une augmentation progressive de la hauteur des cellules. Essayez d’exécuter le projet Expand . Il existe également un projet de sorting et de filtrage avec sorting et filtrage animés. Les deux projets vous permettent de basculer entre la disposition du stream et la disposition de la grid pour que vous puissiez voir l’amélioration.