135 votes

Comment déterminer la hauteur de UICollectionView avec FlowLayout ?

J'ai un UICollectionView avec un UICollectionViewFlowLayout et je veux calculer la taille de son contenu (pour le retour en intrinsicContentSize nécessaire pour ajuster sa hauteur via AutoLayout).

Les problèmes sont : Même si j'ai une hauteur fixe et égale pour toutes les cellules, je ne sais pas combien de "rangées"/lignes j'ai dans le tableau de bord. UICollectionView . Je ne peux pas non plus déterminer ce nombre par le nombre d'éléments de ma source de données, puisque les cellules représentant les éléments de données varient en largeur, et donc le nombre d'éléments que j'ai dans une ligne de l'écran. UICollectionView .

Comme je n'ai pas trouvé d'indications à ce sujet dans la documentation officielle et que la recherche sur Internet ne m'a pas permis d'aller plus loin, toute aide ou idée serait très appréciée.

274voto

Ignatius Tremor Points 1379

Whoa ! Pour une raison quelconque, après des heures de recherche, j'ai maintenant trouvé une réponse assez simple à ma question : Je cherchais complètement au mauvais endroit, en fouillant dans toute la documentation que je pouvais trouver sur UICollectionView .

La solution simple et facile réside dans la mise en page sous-jacente : Il suffit d'appeler collectionViewContentSize sur votre myCollectionView.collectionViewLayout et vous obtenez la hauteur et la largeur du contenu en tant que CGSize . C'est aussi simple que cela.

42voto

user1046037 Points 1812

Si vous utilisez Mise en page automatique alors vous pouvez créer une sous-classe de UICollectionView

Si vous utilisez le code ci-dessous, vous n'avez pas à spécifier de contraintes de hauteur pour la vue de la collection, car elle varie en fonction du contenu de la vue de la collection.

La mise en œuvre est présentée ci-dessous :

@interface DynamicCollectionView : UICollectionView

@end

@implementation DynamicCollectionView

- (void) layoutSubviews
{
    [super layoutSubviews];

    if (!CGSizeEqualToSize(self.bounds.size, [self intrinsicContentSize]))
    {
        [self invalidateIntrinsicContentSize];
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize intrinsicContentSize = self.contentSize;

    return intrinsicContentSize;
}

@end

25voto

lee Points 3543

Sur viewDidAppear vous pouvez l'obtenir par :

float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;

Peut-être que lorsque vous rechargez les données, vous devez calculer une nouvelle hauteur avec les nouvelles données, alors vous pouvez l'obtenir par : ajouter un observateur pour écouter quand votre CollectionView fini de recharger les données à viewdidload :

[self.myCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];

Ensuite, ajoutez la fonction ci-dessous pour obtenir la nouvelle hauteur ou faire quoi que ce soit après le rechargement de la collectionview :

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary  *)change context:(void *)context
{
    //Whatever you do here when the reloadData finished
    float newHeight = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;    
}

Et n'oubliez pas d'enlever l'observateur :

[self.myCollectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];

13voto

Code Swift 3 pour la réponse de l'utilisateur1046037

import UIKit

class DynamicCollectionView: UICollectionView {

    override func layoutSubviews() {
        super.layoutSubviews()
        if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
            self.invalidateIntrinsicContentSize()
        }

    }

    override var intrinsicContentSize: CGSize {
        return contentSize
    }

}

12voto

Nick Wood Points 260

User1046037 réponse en Swift...

class DynamicCollectionView: UICollectionView {
    override func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize() {
            invalidateIntrinsicContentSize()
        }
    }

    override func intrinsicContentSize() -> CGSize {
        return self.contentSize
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X