J'ai un UICollectionViewController qui utilise un UICollectionViewFlowLayout
standard pour afficher une seule colonne verticale de cellules. J'essaie de créer une animation de développement/réduction sur une cellule lorsqu'une cellule est tapée. J'utilise le code suivant pour accomplir cela:
- (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 objet de gestion indique au modèle de données de renvoyer une taille développée ou réduite à l'intérieur de heightForCellAtIndexpath:
[self.collectionView performBatchUpdates:nil completion:nil];
Puis le performBatchUpdates:completiong:
la méthode anime bien ce changement de taille. Toutefois! Lorsque l'animation se produit, la cellule en expansion peut provoquer une cellule partiellement visible au bas de l'écran pour disparaître de l'écran.
Si c'est le cas et que je réduis cette cellule par la suite, la cellule maintenant hors écran s'alignera à son ancienne position sans animation, tandis que toutes les autres cellules visibles s'animeront comme vous le souhaitez. Mon intuition dit que c'est le comportement correct car la cellule est hors écran lorsque l'animation de repli est en cours et n'est pas incluse dans le processus de rendu d'animation. Ma question devient, comment puis-je empêcher que cela se produise?
Je préférerais que toutes les cellules s’animent ensemble, qu’elles soient hors écran ou non. Des pensées?
Il s'agit d'un bogue UICollectionViewFlowLayout
, mais il existe une solution de contournement. Le problème est que les attributs renvoyés par initialLayoutAttributesForAppearingItemAtIndexPath:
ont les mauvais cadres. Plus précisément, ils ont les images 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 images correctes. La structure de base de la substitution ressemblerait à ceci:
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
UICollectionViewLayoutAttributes *pose = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
if (<test for incorrect frame>) {
CGRect frame = pose.frame;
frame.Origin.y = <calculate correct frame>;
pose.frame = frame;
}
return pose;
}
Vous serez responsable d'identifier les scénarios dans lesquels les cadres 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 brut et j'ai pu obtenir une animation fluide.
Généralisant un peu, d'après mon expérience, il y a UICollectionViewFlowLayout
tellement bogué et il y a tellement de cas de coin à gérer si vous avez des éléments qui montent et sortent de l'écran combinés avec des insertions, des suppressions ou des mouvements, que j'ai trouvé plus facile de rouler mes propres mises en page simples. Si vous n'allez pas faire d'insertions, de suppressions ou de mouvements, alors remplacer UICollectionViewFlowLayout
pourrait bien être votre meilleur choix.
Faites-moi savoir si vous avez besoin de plus d'aide.
[~ # ~] modifier [~ # ~]
Si vous êtes intéressé à regarder une disposition de tiers, j'ouvre la source de ma disposition de grille personnalisée VCollectionViewGridLayout et j'ai ajouté un exemple de projet démontrant une hauteur de cellule en expansion lisse. Essayez d'exécuter Expand project . Il existe également un projet Trier & Filtrer avec tri et filtrage animés. Les deux projets vous permettent de basculer entre la disposition du flux et la disposition de la grille afin que vous puissiez voir l'amélioration.